题目描述
你有一架天平和 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
题解
#include <iostream>
#include <cstdio>
#include <cmath>
using namespace std;
const int N = 110, W = 1e5+10 ;
int n, w[N], f[N][W], sum = 0;
int main()
{
cin>>n;
for(int i = 0; i < n; i++)
{
cin>>w[i];
f[i][w[i]] = 1;
sum += w[i]; //得到总重量,即可能称量的重量最大值
}
//i表示砝码编码,j表示重量
for(int i = 1; i < n; i++) //枚举i(即求出使用0~i号砝码能得到的所有状态)
{
for(int j = 1; j <= sum; j++) //对所有可能的重量进行进行枚举
{
if(f[i-1][j]) //若使用0~i-1号砝码可以称量出j重量
{ //注意此处的j重量,可以理解为全在天平的某一侧
f[i][j] = 1; //那么不使用i号砝码也能称量出j重量
f[i][j+w[i]] = 1; //i号砝码放在j重量的同一侧
f[i][int(abs(j-w[i]))] = 1; //i号砝码放在j重量的另一侧
}
}
}
int cnt = 0;
for(int i = 1; i <= sum; i++) //累计f[n-1][]存在的状态,即所有可能称量的重量
cnt += f[n-1][i];
cout<<cnt;
return 0;
}