题目描述
枫落有一个长度为 nnn 的数组,你可以从这 nnn 个数中任选 x (x≥1)x\ (x\ge1)x (x≥1) 个构成一个集合,定义一个集合的权值为该集合的数字之和,现在枫落想要问你一共可能构成多少种不同的权值。
输入描述:
第一行一个正整数 n (1≤n≤103),表示数组长度。 第二行 n 个整数 ai (1≤ai≤104),表示数组中第 i 个元素的值。 数据保证 a1+a2+a3+...+an≤104a_1+a_2+a_3+...+a_n\le10^4a1+a2+a3+...+an≤104
输出描述:
输出一行一个整数,表示可能构成的权值的种数。
示例1
输入
3
1 2 3
输出
6
dp背包问题
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define endl '\n'
const int N=1e6;
int f[N],a[N];
int main(){
ios::sync_with_stdio(0);cin.tie(0),cout.tie(0);
int n,sum=0;
cin>>n;
for(int i=1;i<=n;i++)cin>>a[i],sum+=a[i];
set<int>q; //用set数组进行去重
for(int i=1;i<=n;i++){
for(int j=sum;j>=a[i];j--){
f[j]=max(f[j],f[j-a[i]]+a[i]);
}
}
for(int i=1;i<=sum;i++){
if(f[i])q.insert(f[i]);
}
cout<<q.size();
return 0;
}