EOJ1488 COIN COLLECTOR 贪心
来源:互联网 发布:ibm软件测试招聘 编辑:程序博客网 时间:2024/06/06 13:15
和舍友打了一个半小时嘴炮,终于搞定了这道题,很开心。本题思路就是构造一个答案a0,a1,a2...... ai是找零的硬币。而需要找零的总钱数就是a0+a1+a2......
贪心策略:
1.因为题目要求是获得最多种未曾获得的硬币,所以我们最开始的想法是将所有没获得的硬币都放进答案中。但是这样真的对吗?假如输入是1 0, 2 0, 3 0。那么找零为6时,1,2,3不会都用到。因为 1 + 2 >= 3,所以在经过3找零后,需要找零的钱<=2,所以1,2至多有一个数被用到。这启发我们假如已经构造了局部最优答案a,b。想要构造更大的答案a,b,c时。当a + b >= c,a,b,c三个数不可能同时用到。所以这个时候我们就要开始删除一个数了,咋删呢?看策略2。
2.假如删除c,因为a + b >= c所以在找零的时候必然会先被c找零,所以这种方法是错误的。那么我们就要从a,b中间删一个,根据题意要使得找零的钱数最少,所以我们删掉a,b中较大的那个b.
3.假如c硬币收藏家已经有了,从答案中删除c
hint:有人可能会想到这样一个问题,我们从答案a,b,c向a,b,c,d拓展时,假如a+b+c>=d,我们要删除c,那么会不会剩下的a+b仍然大于d呢?即我们要连续删除多个数直至前面的和小于后面。答案是否定的!!最多删除一个数。假如a+b+c>=d 且 a+b>=d。由于a,b,c是已经构造好的答案,所以还有a+b<c。我们得出c>a+b>=d,即c>d的荒谬结论,c面值肯定小于d,因为我们是按面值从小到大拓展的。
举个例子:输入是
7 25
1 0
2 0
3 1
5 0
10 0
13 0
20 0
先构造答案1 2
构造1 2 3
发现1 + 2 >= 3
删除2
又因为3已经有了
删除3
构造的答案就是1
再构造1 5
再构造1 5 10
因为1 + 5 < 10所以可用
再构造1 5 10 13
因为1 + 5 + 10 >= 13
所以删除10
因为13没有
所以答案是1 5 13
再构造 1 5 13 20
发现1 + 5 + 13 + 20 > k - 1超出限制
所以删掉20
即最后的答案就是 1 5 13
收藏家需要花的钱是k - (1 + 5 + 13) = 6
具体代码如下:
#include <algorithm>#include <iostream>#include <iterator>#include <sstream>#include <fstream>#include <istream>#include <ostream>#include <complex>#include <cstring>#include <utility>#include <cstdlib>#include <cstdio>#include <vector>#include <string>#include <cctype>#include <ctime>#include <cmath>#include <queue>#include <stack>#include <list>#include <new>#include <set>#include <map> using namespace std; const int maxn = 500000 + 5;const int INF = 0x3f3f3f3f;typedef long long int LL;typedef vector<LL> vec; vec ans;//保存答案 int main(){ //freopen("1.txt", "r", stdin); LL n, k; scanf("%I64d%I64d", &n, &k); LL sum = 0; for (int i=0; i<n; i++) { LL p, has; scanf("%I64d%I64d", &p, &has); if (sum >= p)//要删去上次答案的最后一项 { sum -= ans[ans.size() - 1]; ans.pop_back(); } if (!has)//如果当前硬币收藏家没有,则加入答案中 { if (sum + p > k - 1) break; ans.push_back(p); sum += p; } } if (sum == 0)//如果硬币收藏家全有,则找零的钱为1 sum = 1; cout << ans.size() << endl << k - sum << endl; return 0;}
- EOJ1488 COIN COLLECTOR 贪心
- UVa11264 - Coin Collector(贪心)
- EOJ1488
- UVa 11264 Coin Collector (选硬币&贪心好题)
- uva 11264 - Coin Collector(dp or 贪心)
- EOJ 1488 Solution Report - Coin Collector
- coin collector(一道测试题)
- 【BZOJ4582】【Usaco2016 open】Diamond Collector 贪心
- .Coin
- Coin
- ***POJ1029 False coin ACM解题报告(贪心难题)
- 2014-2015 CT S02E10 C题 Coin Graph 构造+贪心
- HDU/HDOJ 2602 Bone Collector(DP,0/1背包,贪心,经典题目)
- 贪心?DP?——BZOJ4582/Luogu3143 [USACO16OPEN]钻石收藏家Diamond Collector
- False coin
- Coin Test
- Coin Toss
- Coin Test
- 51单片机做计时器
- Windows配置MySQL(5.6.20)免安装版
- Android中Dialog数据的获取报错空指针问题
- 在apache配置ecdsa加密套件
- 并发this.getName()和Thread.currentThread().getName()区别
- EOJ1488 COIN COLLECTOR 贪心
- PAT_自测4_Have Fun with Numbers
- 开始啦
- 公钥密码学
- Vista RC vs. pagefile攻击
- Error:Execution failed for task ':app:compileDebugJavaWithJavac'.解决方案
- python中时间相加问题
- socket.io node.js mysql
- 教你怎么制作高大上的三维热力图