题目
题目描述
你有一架天平和N 个砝码,这N 个砝码重量依次是W1, W2, … , WN。 请你计算一共可以称出多少种不同的重量? 注意砝码可以放在天平两边。
输入格式
输入的第一行包含一个整数N。
第二行包含N 个整数:W1, W2, W3, … , WN。
对于50% 的评测用例,1 ≤ N ≤ 15。
对于所有评测用例,1 ≤ N ≤ 100,N 个砝码总重不超过100000。
输出格式
输出一个整数代表答案。
输入样例
3
1 4 6
输出样例
10
import java.util.Scanner;
public class a砝码称重 {
//N个砝码,总重量
static int N,sum;
//记录状态 dp
static int[][] dp;
//砝码数
static int[] arr;
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
N = sc.nextInt();
sum = 0;
arr = new int[N+1];
//记录能称出的总数
int ans = 0;
for (int i = 1; i <= N; i++) {
arr[i] = sc.nextInt();
sum += arr[i];
}
//N+1
dp = new int[N+1][sum*2];
//选前i个砝码去称重
for (int i = 1; i <= N; i++) {
for (int j = 1; j <= sum; j++) {
//模拟 1 4 6
//i == 1 arr[i] = 1
//j 从1到sum总重量开始遍历
//j == 1 arr[1] = 1 成立
//j == 2 状态转移 都不成立 下一轮
//i == 2 arr[2] = 4
//j == 1 dp[1][1] = 1 dp[1][abs(1-4)] = null dp[1][2 + 4] =null //j到3,6时赋值1下一轮
if (arr[i] == j){
dp[i][j] = 1;
}else {
//三种状态//不加砝码|做减法可能会负数abs|做加法 在上一组所有可能的基础上进行状态转移
// dp[i-1][j]把上一个砝码的值赋予这个砝码
dp[i][j] = dp[i-1][j] | dp[i-1][Math.abs(j-arr[i])] | dp[i-1][j+arr[i]];//如果其中有一个满足就等于1,表示可以称出
}
}
}
for (int j = 1; j <= sum; j++) {
if(dp[N][j]==1)ans++;
}
System.out.println(ans+"");
}
}