蓝桥杯1447 砝码称重
问题描述
你有一架天平和 N 个砝码,这 N 个砝码重量依次是 W1,W2,⋅⋅⋅,WN。
请你计算一共可以称出多少种不同的重量? 注意砝码可以放在天平两边。
输入格式
输入的第一行包含一个整数 N。
第二行包含 N 个整数:W1,W2,W3,⋅⋅⋅,WN。
输出格式
输出一个整数代表答案。
样例输入
3
1 4 6
样例输出
10
样例说明
能称出的 10 种重量是:1、2、3、4、5、6、7、9、10、11。
1=1;
2=6−4(天平一边放 6,另一边放 4);
3=4−1;
4=4;
5=6−1;
6=6;
7=1+6;
9=4+6−1;
10=4+6;
11=1+4+6。
评测用例规模与约定
对于 50的评测用例,1≤N≤15。
对于所有评测用例,1≤N≤100,N1≤N≤100,N个砝码总重不超过 100000。
#include<iostream>
#include<cmath>
using namespace std;const int N = 110;
const int M = 2e5+10; //j的范围是 [-m, m],M为最大可能重量的两倍
int n;
int m; //总重量
int w[N];
bool f[N][M]; //f[i][j]:前i个砝码能否称出重量j
int ans;int main()
{cin>>n;for(int i=1; i<=n; ++i){cin>>w[i];m += w[i];}f[0][0]=1; //初始化:0个砝码称出0//枚举前i个砝码for(int i=1; i<=n; ++i){//枚举所有可能的重量for(int j=0; j<=m; ++j){//不选当前砝码 || 选砝码放到左盘 || 选砝码放到右盘f[i][j]=f[i-1][j] || f[i-1][abs(j-w[i])] || f[i-1][j+w[i]];}}for(int i=1; i<=m; ++i){if(f[n][i]) ans++;}cout<<ans;return 0;
}