qdu-凑数题(01背包)
Description
小Q手里有n(n<=1000) 个硬币,每枚硬币有一定的金额(200=>x>=1)他想知道,用这些硬币(每枚硬币只能用一次,但可能会有等面值的用两次) 能组成多少种不同的金额?
Input
第一行 n,表示第二行一共有n个数字,第二行 表示n个数字
Output
第一行 输出 m, 表示可以组成多少种不同的金额第二行 按照从小到大的顺序输出所有的金额。 注意,每行的结尾,不要有空格,否则你的答案可能会被判错。
Sample Input 1
2 1 2
Sample Output 1
3 1 2 3
Sample Input 2
2 1 1
Sample Output 2
2 1 2
01背包的未装满的情况
代码:
#include<cstdio> #include<iostream> #include<cstring> #include<algorithm> #include<queue> #include<stack> #include<set> #include<vector> #include<map> #include<cmath> #define Inf 0x3f3f3f3f const int maxn=1e5+5; typedef long long ll; using namespace std; int a[maxn],dp[200005]; int main() { int n; cin>>n; int sum=0; for(int t=1;t<=n;t++) { scanf("%d",&a[t]); sum+=a[t]; } for(int t=1;t<=sum;t++) { dp[t]=-Inf; } dp[0]=0; for(int t=1;t<=n;t++) { for(int j=sum;j>=a[t];j--) { dp[j]=max(dp[j],dp[j-a[t]]+a[t]); } } int s[200005]; int cnt=0; for(int t=1;t<=sum;t++) { if(dp[t]>=0) { s[cnt++]=dp[t]; } } cout<<cnt<<endl; for(int t=0;t<cnt;t++) { if(t==0) { printf("%d",s[t]); } else { printf(" %d",s[t]); } } return 0; }
作者:李斌
-------------------------------------------
个性签名:独学而无友,则孤陋而寡闻。做一个灵魂有趣的人!
如果觉得这篇文章对你有小小的帮助的话,记得在右下角点个“推荐”哦,博主在此感谢!
万水千山总是情,打赏一分行不行,所以如果你心情还比较高兴,也是可以扫码打赏博主,哈哈哈(っ•̀ω•́)っ✎⁾⁾!
【推荐】还在用 ECharts 开发大屏?试试这款永久免费的开源 BI 工具!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步