zzuli 1432 背包again(求最小不能被得到的价值
来源:互联网 发布:知乎安卓屏幕录像软件 编辑:程序博客网 时间:2024/05/22 21:18
1432: 背包again
时间限制: 1 Sec 内存限制: 128 MB提交: 147 解决: 36
[提交][状态][讨论版]
题目描述
Gy最近学习了01背包问题,无聊的他又想到了一个新的问题,给定n个物品的价值,和01背包一样,每个物品只能选1次或0次,求最小不能被得到的价值。
输入
第一行一个正整数T(T <= 100),表示有T组数据。
每组数据输入格式如下:
第一行为一个正整数N(N<=100),表示物品个数。
第二行N个正整数,表示每个物品的价值vi(1<=vi<=1000000)
输出
共输出T行,即每组数据相应答案。
样例输入
232 4 841 2 4 8
样例输出
116
本题看似dp问题,但观察物品价值的范围即可发现普通的背包解法是无法在规定时间内解决的,所以需要换一种思路来考虑
看第二组样例数据,明显是在提示我们去想1 2 4 8 16 32。。。这个数列a[1]=1, a[i]=a[i-1]*2,这个数列的特点是其前i项,可以通过加法组合得到所有小于第i+1项的数。
例如对于前3项1 2 4这三个数,
1=1
2=2
3=1+2
4=4
5=1+4
6=2+4
7=1+2+4
而a[4]=8,1~7都可得到。
方便记忆,将1 2 4 8 16。。。这个数列记为数列cp,先通过以下程序打出cp数列,因为已经给定物品价值范围不会大于1000000,所以只需算到刚大于1000000那一项即可
#include<iostream>using namespace std;int main(){int i=1;freopen("out.txt","w",stdout);cout<<i<<',';while(true){i=(i<<1);cout<<i<<',';if(i>1000000)break;}return 0;}
从输出的文本中得到以下序列,范围内的有20个
1,2,4,8,16,32,64,128,256,512,1024,2048,4096,8192,16384,32768,65536,131072,262144,524288,1048576,
接下来,对于本题,将输入序列记为ain,先将其排序后记为a
求解步骤如下:
以a为1 2 3 4为例
1、尽量从a序列中依序取出cp数列中的元素;
(即取出了1 2 4,1 2 4可表示出1~7,记ans=8
2、从a剩下的数中取最小值m
1)若m>ans,最终结果即为ans,完成!
2)若m<=ans,ans+=m,从a中移除m,goto 2
(即对于a中经过第1步,剩下的数字为3,3<8,那么:8=3+5=3+(1+4), 9=3+6=3+(2+4), 10=3+7=3+(1+2+4),即ans=3+8=11
若对于a为1 2 4 9,因为9>8,8就无法取到了,所以得到最终答案为8.
代码:
#include<iostream>#include<algorithm>#include<cstdio>#include<vector>#include<list>using namespace std;int main(){vector<int> ain;list<int> a;int num;int cp[50]={1,2,4,8,16,32,64,128,256,512,1024,2048,4096,8192,16384,32768,65536,131072,262144,524288,1048576};while(cin>>num){while(num--!=0){int n,pb;cin>>n;ain.clear();a.clear();for(int i=1;i<=n;++i){scanf("%d",&pb);ain.push_back(pb);}sort(ain.begin(),ain.end());for(int i=0;i!=ain.size();++i){a.push_back(ain[i]);}int ans=1,j=0;for(list<int>::iterator i=a.begin();i!=a.end()&&j<20; ){if(*i==cp[j]){ans=cp[j+1];i=a.erase(i);++j;continue;}++i;}for(list<int>::iterator i=a.begin();i!=a.end();++i){if(*i>ans){break;}else{ans+=(*i);}}cout<<ans<<endl;}}return 0;}
Ps:代码中用到了vector,后来又换成list,因为vector的表操作时间消耗是O(n),而list仅花费常数时间
- zzuli 1432 背包again(求最小不能被得到的价值
- hdu1114 Piggy-Bank(完全背包,求最小价值)
- Piggy-Bank (装满背包的最小价值)
- 动态规划--装满背包的最小价值--hdu1114 Piggy-bank
- hdu2639(求价值第K大的01背包)
- hdu1114——Piggy-Bank(完全背包求最小价值)
- 完全背包(满且价值最小)
- 01背包(求前一个的最大价值-->求前K个的最大价值) 之 hdu 2639
- 【POJ 1651】【区间DP 矩阵链乘的变形】Multiplication Puzzle【一串数字,除了头尾不能动,每次取个数字,它与左右相邻数字的乘积为其价值,求价值和最小】
- zzuli oj 1917 连续子序列的价值和
- zzuli OJ 1006: 求等差数列的和
- zzuli OJ 1014: 求三角形的面积
- HDU 4738 Caocao's Bridges(求价值最小的桥)
- 1114 Piggy-Bank - 完全背包 恰好达到状态最小价值
- 背包again
- google笔试题 -- 根据已知数列得到不能组合求和的最小数
- 强连通缩点,求最小价值!hdu5934
- hdu5501 变价值的01背包
- [ACM] 携程预赛第一场 括号匹配 (动态规划)
- 关闭浏览器弹出提示的兼容问题陈述
- Chapter06-Mondriaan's Dream(POJ 2411)(状态压缩DP)
- head first dubbo
- UVa 10014 - Simple calculations
- zzuli 1432 背包again(求最小不能被得到的价值
- STL中vector删除一个元素
- POJ 3561
- 对Java中多态的认识总结
- Leetcode Longest Substring Without Repeating Characters
- 数字到字符串、字符串到数字的转换
- 阶乘
- Java中尽量使用StringBuilder和StringBuffer进行字符串连接
- java环境变量