HDU_5527_Too Rich
2018-06-17 21:49:14来源:未知 阅读 ()
Too Rich
Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 262144/262144 K (Java/Others)
Total Submission(s): 1410 Accepted Submission(s): 362
For example, if p=17 and you have two $10 coins, four $5 coins, and eight $1 coins, you will pay it by two $5 coins and seven $1 coins. But this task is incredibly hard since you are too rich and the sticker is too expensive and pusheen is too lovely, please write a program to calculate the best solution.
1≤T≤20000
0≤p≤109
0≤ci≤100000
- 首先由于p的数值范围的缘故排除用完全背包来解
- 用dfs枚举纸币张数爆搜肯定会tle
- 所以往贪心的思想考虑
- 朴素的想法是对于p从小面额的凑到大面额的纸币
- 但是这道题中纸币的面额如果以倍数为关系建图可以发现(20,50)和(200,500)会分别从10和100的节点分叉,但是其他节点均可表示比当前节点大的所有面额的纸币
- 这个特性意味着用小面额20或200有凑不出50和500以及其奇数倍数值的情况
- 反思之前提到的朴素的贪心想法
- 如果凑到最后出现凑的数额不等于p
- 则一定是最后加的当前最大面额导致的
- 补救的办法应是用之前使用的小面额纸币凑当前导致超范围的纸币的面额
- 那么如之前所述
- 10种纸币的面额不是一种很好的结构
- 不能保证小面额纸币一定可以凑成任意大面额纸币
- 就存在不可补救的情况存在
- 而且我们没法保证当前凑数的结果是正确的凑数结果
- 那有没有补救的办法呢?
- 还是有滴呀
- 只要把纸币面额更改成最优结构即可
- 就是每次使用两张50或500,就把这种面额的纸币算是取消了
- 之后就剩下8种面额的纸币,而且都满足可以凑成任意比当前面额大的纸币的条件
- 剩下的就是讨论50和500两种纸币使用张数奇偶性的问题了
- 4种情况,在贪心前加上就行
- 高中数学老师讲得好啊!“正难则反”
- 这个题就可以反向思维,只要凑出纸币剩余面额的最小张数,减一下就是结果啊!
- 如果正向考虑,应该是贪心凑数,最后对于多出来的数值用小面额先代替大面额之后打补丁
- 好吧,很麻烦
- 但是反向来做,不用代替和打补丁,就是直接用最大面值来凑,不存在打补丁的问题
1 #include <iostream> 2 #include <string> 3 #include <cstdio> 4 #include <cstring> 5 #include <algorithm> 6 #include <climits> 7 #include <cmath> 8 #include <vector> 9 #include <queue> 10 #include <stack> 11 #include <set> 12 #include <map> 13 using namespace std; 14 typedef long long LL ; 15 typedef unsigned long long ULL ; 16 const int maxn = 1e5 + 10 ; 17 const int inf = 0x3f3f3f3f ; 18 const int npos = -1 ; 19 const int mod = 1e9 + 7 ; 20 const int mxx = 100 + 5 ; 21 const double eps = 1e-6 ; 22 const double PI = acos(-1.0) ; 23 24 int c[11]={0,1,5,10,20,50,100,200,500,1000,2000}; 25 int a[20], b[20], T, ans, tot; 26 LL p, sum; 27 int main(){ 28 // freopen("in.txt","r",stdin); 29 // freopen("out.txt","w",stdout); 30 while(~scanf("%d",&T)){ 31 while(T--){ 32 sum=0; 33 tot=0; 34 ans=inf; 35 scanf("%lld",&p); 36 for(int i=1;i<11;i++){ 37 scanf("%d",&a[i]); 38 tot+=a[i]; 39 sum+=a[i]*c[i]; 40 } 41 if(sum<p){ 42 printf("-1\n"); 43 continue; 44 } 45 p=sum-p; 46 memcpy(b,a,sizeof(a)); 47 for(int i=0;i<2;i++) 48 for(int j=0;j<2;j++) 49 if(i<=a[5] && j<=a[8]){ 50 b[5]=a[5]-i; 51 b[8]=a[8]-j; 52 LL t=p-i*c[5]-j*c[8]; 53 int cnt=i+j; 54 for(int k=10;k>0&&t>0;k--){ 55 int del=min(b[k],(int)t/c[k]); 56 if((k==5||k==8)&&(del&1)) 57 del--; 58 t-=del*c[k]; 59 cnt+=del; 60 } 61 if(t==0) 62 ans=min(ans,cnt); 63 } 64 if(ans==inf) 65 ans=-1; 66 else 67 ans=tot-ans; 68 printf("%d\n",ans); 69 } 70 } 71 return 0; 72 }
标签:
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有
上一篇:深度优先搜索——地宫取宝
- HDU-2955-Robberies(0-1背包) 2020-03-30
- hdu1455 拼木棍(经典dfs) 2020-02-29
- anniversary party_hdu1520 2020-02-16
- hdu1062 text reverse 2020-01-27
- hdu4841 2020-01-26
IDC资讯: 主机资讯 注册资讯 托管资讯 vps资讯 网站建设
网站运营: 建站经验 策划盈利 搜索优化 网站推广 免费资源
网络编程: Asp.Net编程 Asp编程 Php编程 Xml编程 Access Mssql Mysql 其它
服务器技术: Web服务器 Ftp服务器 Mail服务器 Dns服务器 安全防护
软件技巧: 其它软件 Word Excel Powerpoint Ghost Vista QQ空间 QQ FlashGet 迅雷
网页制作: FrontPages Dreamweaver Javascript css photoshop fireworks Flash