新年趣事之打牌----VIJOS_1071----01背包加强版
来源:互联网 发布:mysql 修改数据表字段 编辑:程序博客网 时间:2024/05/16 04:57
题目地址:http://www.vijos.org/Problem_show.asp?id=1071
From xiaomengxian新年趣事之打牌 新年趣事 系列 描述 Description 过年的时候,大人们最喜欢的活动,就是打牌了。xiaomengxian不会打牌,只好坐在一边看着。
这天,正当一群人打牌打得起劲的时候,突然有人喊道:“这副牌少了几张!”众人一数,果然是少了。于是这副牌的主人得意地说:“这是一幅特制的牌,我知道整副牌每一张的重量。只要我们称一下剩下的牌的总重量,就能知道少了哪些牌了。”大家都觉得这个办法不错,于是称出剩下的牌的总重量,开始计算少了哪些牌。由于数据量比较大,过了不久,大家都算得头晕了。
这时,xiaomengxian大声说:“你们看我的吧!”于是他拿出笔记本电脑,编出了一个程序,很快就把缺少的牌找了出来。
如果是你遇到了这样的情况呢?你能办到同样的事情吗?
输入格式 Input Format 第一行一个整数TotalW,表示剩下的牌的总重量。
第二行一个整数N(1<N<=100),表示这副牌有多少张。
接下来N行,每行一个整数Wi(1<=Wi<=1000),表示每一张牌的重量。
输出格式 Output Format 如果无解,则输出“0”;如果有多解,则输出“-1”;否则,按照升序输出丢失的牌的编号,相邻两个数之间用一个空格隔开。 样例输入 Sample Input270
4
100
110
170
200
样例输出 Sample Output
2 4
首先要理解题目的意思。这个题目的意思是说,现在有一堆丢失了的牌,知道他们的总重量,然后知道每一种牌的重量,要你求到底是丢失了哪几张牌。如果无法确定则输出0,如果有很多种情况,则输出-1,否则按牌号的大小一次输出缺的牌。
由于本题目引入了重量的概念,所以既然剩下的牌的总重量知道,那我只需要用01背包方法求出怎样才能用给出的牌种组成剩下的牌,没拿进来的牌就是缺的牌。只不过我们要对这个做一个记录。记录哪些牌拿进来了,哪些没有。用一个数组judge[i]来记录是否加进来了。用数组num[v]来记录当把容量为V的正好装满的时候所用的牌的牌号i,用dp[v]来表示装满容量为v的所有方案数。初值dp[0]=1,其余为0.下面上代码更容易懂。
#include<iostream>using namespace std;#define N 101000int dp[N];int num[N];int a[100];bool judge[100]; int main(){int total;while(scanf("%d",&total) != EOF){int n;scanf("%d",&n);int i;for(i=1;i<=n;i++){ scanf("%d",&a[i]);judge[i] = false;} for(i=0;i<=total;i++){dp[i] = 0;num[i] = 0; } dp[0] = 1; for(i=1;i<=n;i++){int v;for(v=total;v>=a[i];v--){ if(dp[v-a[i]]) //dp[v-a[i]]是有效状态 {dp[v]+=dp[v-a[i]]; //加上用自己的方案数机上前面的方案数 if(!num[v])num[v] = i; } } }if(dp[total] == 0)printf("0\n");else if(dp[total] > 1)printf("-1\n"); else{int v = total; while(v) //记录将背包容量为total装满的背包取值路径 {judge[num[v]] = true; //将在这个路径上的置为true,后面输出false即为不在路径上的 v -= a[num[v]]; }for(i=1;i<=n;i++)if(!judge[i]) //输出不在路径上的 printf("%d ",i); } }return 0; }
- 新年趣事之打牌----VIJOS_1071----01背包加强版
- 新年趣事之打牌----VIJOS_1071----01背包加强版
- 新年趣事之打牌(01背包+记录路径)
- vijosp1071-01背包&记录组合&细节-新年趣事之打牌
- 新年趣事之打牌
- 新年趣事之打牌
- 新年趣事之打牌
- 新年趣事之打牌_DP
- vijosP1071 新年趣事之打牌
- 1071.新年趣事之打牌
- vijos 1071 新年趣事之打牌
- Vijos - P1071 新年趣事之打牌
- vijos P1071新年趣事之打牌
- Vijos P1071新年趣事之打牌
- Vijos P1071 新年趣事之打牌
- Vijos P1071 新年趣事之打牌(动态规划,背包,统计方案数)
- 【动态规划】Vijos P1071 新年趣事之打牌
- 1071新年趣事之打牌——vijos
- 《Linux——C 笔记1》
- AF_UNSPEC、AF_INET和AF_INET6之间的关系
- 2012-7-20 周五 总结
- 校验和
- DirectX游戏编程入门——第二部分(游戏编程工具箱) ——精灵变换
- 新年趣事之打牌----VIJOS_1071----01背包加强版
- 签了工作之后才发现,自己太草率了.....我看过的关于职业规划最好最全面的一篇文章
- Linux下实现不同网段之间的访问
- 广播数据包的接收
- Java 设计模式 之 状态模式(State)
- Android_Graphics学习-Canvas save() restore()的简单理解
- Openstack个人理解及各部分解释(一)
- 对鸟哥私房菜的学习——第十一章,3.命名别名与历史命令
- 2012.7.20总结