题目描述
你有一架天平和 NN 个砝码, 这 NN 个砝码重量依次是 W_{1}, W_{2} ,⋯,W_{N}。 请你计算一共可以称出多少种不同的重量?
注意砝码可以放在天平两边。
输入格式:
输入的第一行包含一个整数 N。
输入的第一行包含一个整数 N。
第二行包含 N 个整数: W_{1}, W_{2}, W_{3}。。。
输出格式:
输出一个整数,表示答案。
输出一个整数,表示答案。
题解
不会写递推,用了一个笨蛋朴素一点的方法,记 dp[i][j]为前 i 个数是否可以表达数字 j,若可以则为 1,不可以则为 0。此时可以知道,若 dp[i-1][j]为 1 则 dp[i][j]也为一,同时可以推出左右各放一次得到的重量也为 1,即 dp[i][j + a[i]]和 dp[i][abs(j – a[i])]也为 1.最后遍历最后一行加和即可。
#include<bits/stdc++.h>
#define ll long long
#define endl "\n"
#define mem(vis, num) memset(vis, num, sizeof(vis));
using namespace std;
int dp[110][100010], a[110];
int main(){
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
mem(dp, 0);
int n, ans = 0;
cin >> n;
for(int i = 1; i <= n; i++){
cin >> a[i];
}
for(int i = 1; i <= n; i++){
dp[i][a[i]] = 1;
for(int j = 1; j <= 100000; j++){
if(dp[i - 1][j] != 0){
dp[i][j] = 1;
dp[i][j + a[i]] = 1;
dp[i][abs(j - a[i])] = 1;
}
}
}
for(int i = 1; i <= 100000; i++){
ans += dp[n][i];
}
cout << ans << endl;
return 0;
}
