【u204】高级砝码称重
来源:互联网 发布:apphtml源码 编辑:程序博客网 时间:2024/05/16 00:25
Time Limit: 1 second
Memory Limit: 128 MB
【问题描述】
现有n个砝码,重量分别为a1,a2,a3,……,an,在去掉m个砝码后,问最多能称量出多少不同的重量(不包括0)。【输入格式】
输入文件weight.in的第1行为有两个整数n和m,用空格分隔 第2行有n个正整数a1,a2,a3,……,an,表示每个砝码的重量。【输出格式】
输出文件weight.out仅包括1个整数,为最多能称量出的重量。
【数据规模】
对于20%的数据,m=0; 对于50%的数据,m≤1; 对于50%的数据,n≤10; 对于100%的数据,n≤20,m≤4,m<n,ai≤100。
Sample Input1
3 11 2 2
Sample Output1
3
【样例说明】
在去掉一个重量为2的砝码后,能称量出1,2,3共3种重量。
【题解】
这是一个0/1背包+搜索的问题。
先选出m个物品,把他们"去掉“,然后对剩余的物品,进行0/1背包就可以了。
ai<=100,n<=20,则枚举的最大重量为2000;
用一个boolean型的bo数组来表示某一个重量是否能达到。
if (can[j-w[i]])
can[j] = true;
最后统计一下重量的种数就可以了。
【代码】
#include <cstdio>#include <cstring>int n,m,w[21],ma = 0;bool bo[21],can[2001]; //bo用来表示哪些砝码可以用,can则表示哪些重量可以由砝码称出 void input_data(){scanf("%d%d",&n,&m);for (int i = 1;i <= n;i++)scanf("%d",&w[i]);}void select(int x,int num) //表示当前枚举到了第x个砝码,去掉的砝码数量为num {if (num == m) //如果去掉的砝码数量达到了要求,则进行一次0/1背包,求出能到达的重量 {memset(can,false,sizeof(can));can[0] = true;for (int i = 1;i <= n;i++)if (bo[i])for (int j= 2000;j>=w[i];j--) //0/1背包是逆序更新的。 if (can[j-w[i]])can[j] = true;int xx = 0;for (int j = 1 ;j <= 2000;j++)if (can[j]) //统计能够到达的重量数目 xx++;if (xx > ma)ma = xx;return;}for (int i = x+1;i <= n;i++) //从x+1开始表示是一个组合问题,从n个中选出m个。 if (bo[i]){bo[i] = false;select(i,num+1);bo[i] = true;}}void get_ans(){memset(bo,true,sizeof(bo));select(0,0);//从0开始,可以包括m==0的情况。 }void output_ans(){printf("%d\n",ma);}int main(){freopen("stronger.in","r",stdin);freopen("stronger.out","w",stdout);input_data();get_ans();output_ans();fclose(stdin);fclose(stdout);return 0;}
0 0
- 【u204】高级砝码称重
- 砝码称重
- 砝码称重
- 砝码称重
- 砝码称重
- 砝码称重
- 砝码称重
- 砝码称重
- 砝码称重
- 砝码称重
- 砝码称重
- 砝码称重
- 砝码称重
- 砝码称重
- 砝码称重
- 砝码称重
- 砝码称重
- 砝码称重
- POJ 3237 Tree (树链剖分+线段树)
- Linux离线安装SVN并配置
- python 读写csv格式的文件
- 2016多校训练Contest7: 1008 Hearthstone hdu5816
- JAVA设计模式-适配器模式
- 【u204】高级砝码称重
- Java多线程三:Runnable接口
- RequestMapping的params参数
- vmware安装无法打开内核设备 \\.\Global\vmx86: 系统找不到指定的文件
- 关于Android中一些异常问题的解决办法
- QT Udp组播
- 各聚类算法比较
- 解剖学概述
- spring mvc 表单提交