描述
现有一组砝码,重量互不相等,分别为m1,m2,m3…mn;
每种砝码对应的数量为x1,x2,x3…xn。现在要用这些砝码去称物体的重量(放在同一侧),问能称出多少种不同的重量。
注:
称重重量包括0
输入描述:
输入包含多组测试数据。
对于每组测试数据:
第一行:n — 砝码数(范围[1,10])
第二行:m1 m2 m3 … mn — 每个砝码的重量(范围[1,2000])
第三行:x1 x2 x3 … xn — 每个砝码的数量(范围[1,6])
输出描述:
利用给定的砝码可以称出的不同的重量数
示例1
输入:
2
1 2
2 1
输出:
5
代码
public class Huawei称砝码 {
/**
* 利用动态规划,多重背包思路 todo牛客网解题思路
*
* @param args
* @throws IOException
*/
public static void main(String[] args) throws IOException {
//动态规划,多重背包的解法,速度比较慢
dp();
//牛客网解法,实际上就是把上面的dp()解法中二维表压缩成数组形式。
niuke();
}
public static void niuke() throws IOException {
// 1.高效读数据
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String mark = null;
while ((mark = br.readLine()) != null) {
int n = Integer.parseInt(mark);
String[] s1 = br.readLine().split(" ");
String[] s2 = br.readLine().split(" ");
int[] weight = new int[s1.length];
int[] nums = new int[s2.length];
int sum = 0;
for (int i = 0; i < n; i++) {
weight[i] = Integer.parseInt(s1[i]);
nums[i] = Integer.parseInt(s2[i]);
sum += weight[i] * nums[i];
}
System.out.println(fama(n, weight, nums, sum));
}
}
public static int fama(int n, int[] weight, int[] nums, int sum){
boolean[] weg = new boolean[sum+1];
weg[0] =true;
weg[sum] = true;
int top = 0;
// 三重循环,分别表示 n个砝码,weight.length 个种类,每个种类有 num.length 个数量
for(int i =0; i< n; i++){
for (int j = 0; j < nums[i]; j++) {
for(int k=top + weight[i]; k>= weight[i];k--){
// weg[k-weight[i]]== true,意思就是 k-weight[i] + weight[i] == k,可以称出 k 重量
if(weg[k -weight[i] ]){
weg[k] = true;
}
}
top += weight[i];
}
}
int count = 0;
for (boolean b : weg) {
if (b) count++;
}
return count;
}
private static void dp() throws IOException {
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
String str;
while ((str = reader.readLine()) != null) {
int n = Integer.parseInt(str);
String[] weightArr = reader.readLine().split(" ");
String[] numArr = reader.readLine().split(" ");
int[] weights = new int[n + 1];
int[] nums = new int[n + 1];
int totalWeight = 0;
for (int i = 1; i <= n; i++) {
weights[i] = Integer.parseInt(weightArr[i - 1]);
nums[i] = Integer.parseInt(numArr[i - 1]);
totalWeight += weights[i] * nums[i];
}
int[][] table = new int[n + 1][totalWeight + 1];
int total = 0;
for (int i = 1; i < table.length; i++) {
for (int j = 0; j < table[i].length; j++) {
if (weights[i] > j) {
table[i][j] = table[i - 1][j];
} else {
int t = j / weights[i];
for (int k = 0; k <= t && k <= nums[i]; k++) {
int w = table[i - 1][j - k * weights[i]] + weights[i] * k;
if (w == j) {
table[i][j] = w;
if (table[i - 1][j] == 0) {
total++;
break;
}
}
}
}
}
}
for (int i = 1; i < table.length; i++) {
for (int j = 0; j < table[i].length; j++) {
System.out.printf("%3s", table[i][j]);
}
System.out.println();
}
System.out.println(total);
}
}
}