当前位置:首页 >> 跨学科知识体系 >> 【qduoj - 纳新题】凑数题(恰好装满类0-1背包 或 母函数),酷派w721

【qduoj - 纳新题】凑数题(恰好装满类0-1背包 或 母函数),酷派w721

cpugpu芯片开发光刻机 跨学科知识体系 2
文件名:【qduoj - 纳新题】凑数题(恰好装满类0-1背包 或 母函数),酷派w721 【qduoj - 纳新题】凑数题(恰好装满类0-1背包 或 母函数)

题干:

描述

 

小Q手里有n枚硬币,每枚硬币有一定的金额x,他想知道,用这些硬币能组成多少种不同的金额。但是他太笨了,自己数懵了,你来帮帮他好不好?

注意:组成金额时,每枚硬币只能用一次,但可以同时使用等面值的不同硬币

输入

 

第一行 n,表示第二行一共有n个数字 第二行 n个数字,表示不同的硬币的面值

单组输入,不用担心

输出

 

第一行 输出 m, 表示可以组成多少种不同的金额 第二行 按照从小到大的顺序输出所有的金额。 注意,每行的结尾,不要有空格,否则你的答案可能会被判错。

输入样例 1 

21 2

输出样例 1

31 2 3

输入样例 2 

21 1

输出样例 2

21 2

提示

n<=1000, x>=1&&x<=200

解题报告:

   不难看出这是道组合数学的题目,解决这类问题(凑种数)有两种方式,背包类dp或者是母函数,这里选用了装满类0-1背包来解决这道题,母函数以后可以自己试试?(这个数据范围应该是够了)

AC代码:

#include<bits/stdc++.h>using namespace std;const int INF = 0x3f3f3f3f;int dp[5000000 + 5],v[5000000 + 5],ans[5000000 + 5];int sum;int main(){int n;cin>>n;for(int i = 1; i<=n; i++) scanf("%d",v+i),sum += v[i];dp[0]=0;for(int i = 1; i<=200000; i++) dp[i] = -INF;for(int i = 1; i<=n; i++) {for(int j = sum; j>=v[i]; j--) {dp[j] = max(dp[j],dp[j-v[i]] + v[i]);}}int cnt = 0;for(int i = 1; i<=200000; i++) {if(dp[i] >= 0) {cnt++;ans[cnt] = i;}} printf("%d\n",cnt);for(int i = 1; i<=cnt; i++) {printf("%d",ans[i]);if(i!=cnt ) putchar(' ');}return 0 ;}//5//100 100//100//100//100

总结:

  没有错,刚开始wa了这么多发,就是因为背包写错了,没加那个max、、、话说啊不到半个月没写背包你就忘这么干净了?

协助本站SEO优化一下,谢谢!
关键词不能为空
同类推荐
«    2025年12月    »
1234567
891011121314
15161718192021
22232425262728
293031
控制面板
您好,欢迎到访网站!
  查看权限
网站分类
搜索
最新留言
文章归档
网站收藏
友情链接