poj3040Allowance
2016-04-01 20:30
330 查看
题意:农夫约翰要给奶牛Bessie发工资了 ,每周至少 C 元。约翰手头上有面值V_i的硬币B_i个,这些硬币的最小公约数为硬币的最小面值。求最多能发几周?
思路:首相将面额大于等于C的硬币,直接发送。对于生下硬币,先从大到小排序,凑出最接近C的面额,不超过C,然后在从小到大,凑出刚好大于等于C的面额。然后修改它们数量,一直重复这个操作。最后所有都凑不出C为止,思路好想,操作不好写。
思路:首相将面额大于等于C的硬币,直接发送。对于生下硬币,先从大到小排序,凑出最接近C的面额,不超过C,然后在从小到大,凑出刚好大于等于C的面额。然后修改它们数量,一直重复这个操作。最后所有都凑不出C为止,思路好想,操作不好写。
#include<cstdio> #include<cstring> #include<functional> #include<limits> #include<algorithm> #include<iostream> #define fi first #define se second using namespace std; typedef pair<int,int>Coin; Coin a[20]; int need[20]; int main() { int n,c; while(~scanf("%d%d",&n,&c)){ for(int i=0;i<n;i++) scanf("%d%d",&a[i].fi,&a[i].se); int ans=0; for(int i=0;i<n;i++){ if(a[i].fi>=c){ ans+=a[i].se; a[i].se=0; } } sort(a,a+n,greater<Coin>()); while(1){ int sum=c; memset(need,0,sizeof(need)); for(int i=0;i<n;i++){ if(sum>0&&a[i].se>0){ need[i]=min(a[i].se,sum/a[i].fi); sum-=need[i]*a[i].fi; } } for(int i=n-1;i>=0;i--){ if(sum>0&&a[i].se>0){ int cause=min(a[i].se-need[i],(sum+a[i].fi-1)/a[i].fi);//允许不超过一个面值的sum if(cause>0){ need[i]+=cause; sum-=cause*a[i].fi; } } } if(sum>0) break; int add=0x7ffffff; for(int i=0;i<n;i++){ if(need[i]==0) continue; add=min(add,a[i].se/need[i]); } ans+=add; for(int i=0;i<n;i++){ if(need[i]==0) continue; a[i].se-=add*need[i]; } } printf("%d\n",ans); } }
相关文章推荐
- 欢迎使用CSDN-markdown编辑器
- 【深入spring】IoC容器的实现
- vmware虚拟机克隆CentOS7 出现的网络问题解决办法
- 环形队列中实现队列的基本运算
- FZU 2104 Floor problem(floor)
- 文章标题
- 解决mysql密码过期问题
- 验证码
- Swift延迟加载的一种用途
- Hdu 3062 Party
- Swift延迟加载的一种用途
- Swift延迟加载的一种用途
- 蓝桥杯_算法提高_排列数(深度搜索、递归)
- 一个简单的时间获取服务器程序
- java之文件
- FatMouse' Trade
- 搜索二维矩阵
- 【BZOJ1458】士兵占领【最大流】
- 深度学习难在哪里?
- 2016-4-01华为校招实习机试