题目
你有一架天平和N个砝码,这N个砝码重量依次是W1,W2,…,WN。
请你计算一共可以称出多少种不同的重量?
注意砝码可以放在天平两边。
输入格式
输入的第一行包含一个整数N。
第二行包含N个整数:W1,W2,…,WN。
输出格式
输出一个整数代表答案
样例输入
3
1 4 6
样例输出
10
如何插入一段漂亮的代码片
参考https://blog.csdn.net/asbbv/article/details/117253522第一种思路
官网测试,可以AC,地址测试
import java.util.Scanner;
public class _06砝码称重_动态规划 {
//dp[i][j]代表前i个元素是否能组成j的重量
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner scanner = new Scanner(System.in);
int n = scanner.nextInt();
int[] aa = new int[n];
int summ = 0;
for (int i = 0; i < n; i++) {
aa[i] = scanner.nextInt();
summ += aa[i];
}
boolean[][] dp = new boolean[n + 1][summ + 1];
//初始化,可以根据样例自己手动画一下,就能看出来了
dp[0][0] = true;
int sum = 0;
for (int i = 1; i < dp.length; i++) {
sum += aa[i - 1];
for (int j = 0; j <= sum; j++) {
if(aa[i - 1] == j)
dp[i][j] = true;
//状态转移条件
if(dp[i - 1][j] == true) {
//第一个转移方程
dp[i][j] = true;
//第二个转移方程
dp[i][j + aa[i - 1]] = true;
//第三个转移方程,如果是负数就跳过
if(j - aa[i - 1] > 0)
dp[i][j - aa[i - 1]] = true;
//第四个转移方程,同三
if(aa[i - 1] - j > 0)
dp[i][aa[i - 1] - j] = true;
}
}
}
//结果,不需要从0开始加,0没意义
int ans = 0;
for (int i = 1; i < dp[0].length; i++) {
if(dp[n][i] == true) {
ans++;
}
}
// //可以把dp打印出来看是否正确
// for (int i = 0; i < dp.length; i++) {
// for (int j = 0; j < dp[0].length; j++) {
// System.out.print(dp[i][j] + " ");
// }
// System.out.println();
// }
System.out.print(ans);
}
}