Greedy:Allowance(POJ 3040)
题目大意:农夫和牛又搞新花样了,现在农夫想给Bessie每个星期都给一点零用钱,农夫有一堆面值的钱币,并且这个钱币都能被上一个钱币整除(1,5,10,50),并且钱币有一定数量,要你求最多可以给多少个星期超过C的零用钱?
这一题如果没有可以被整除的条件,那只能用动态规划了,但是这一题给了这个条件,那就说明,我们的组合都是满足单一原则的(比如单次组合最接近c的组合总是从大到小,再从小到大排列面额数,而没有其他组合),也就是可以贪婪算法。
这个贪婪算法可以分成三个步骤:
S1:如果钱币的面值大于C,那就直接一个一个星期分
S2:如果钱币的面值小于C,那么我们就从大到小排列钱币,直到大于大于等于C为止
S3:如果S2以后,钱币数任然达不到要求,那么我们就从小到大排列从新再找,直到大于C为止
如果S4以后,还是不能找到大于C的组合,那么直接退出即可
这样的贪婪的原理是因为,我们的硬币总是等效的,因为他在达到C可以分发的情况下只是数量的区别,所以我们想尽量让我们的组合数靠近C。
其他东西在代码的注释上应该写的很清楚噜
#include <iostream>
#include <functional>
#include <algorithm> using namespace std; typedef struct money
{
int value;
int numbers;
}Coin_Set;
int fcomp(const void *a, const void *b)
{
return (int)((*(Coin_Set *)b).value - (*(Coin_Set *)a).value);
} static Coin_Set coins[];
static int used[]; void Search(const int, const int); int main(void)
{
int n, least_V; while (~scanf("%d%d", &n, &least_V))
{
for (int i = ; i < n; i++)
scanf("%d%d", &coins[i].value, &coins[i].numbers); qsort(coins, n, sizeof(Coin_Set), fcomp);//先按照面值排序(从大到小)
Search(n, least_V);
} return ;
} void Search(const int n, const int least_V)
{
int ans = , i, pos, j, min_ans_tmp, used_tmp, last; //Step1:如果比least_v大,直接加入ans中
for (i = ; i < n && coins[i].value >= least_V; i++)
{
ans += coins[i].numbers;
coins[i].numbers = ;
}
for (pos = i;;)
{
memset(used, , sizeof(used));
//Step2:尽量凑到least_V之前
last = least_V;
for (j = pos; j < n; j++)
{
used_tmp = min(last / coins[j].value, coins[j].numbers);//先设定好一个last要分到多少枚j硬币 //注意,上一步如果last<coins[j].value的时候,返回为0,下面相当于不更新last和used
last -= coins[j].value * used_tmp;
used[j] = used_tmp;
}
//Step3:从后往前,凑到比least_V大为止
for (j = n - ; j >= && last > ; j--)
{
used_tmp = (last + coins[j].value - ) / coins[j].value;
used_tmp = min(used_tmp, coins[j].numbers - used[j]);//上一个循环用掉了一些哦,一定要注意 //上同
last -= coins[j].value*used_tmp;
used[j] += used_tmp;//注意是“+=”,因为会重复
}
if (last > ) break;//凑不齐,直接退出 min_ans_tmp = INT_MAX;
for (j = pos; j < n; j++)//找到可以完全分配到的最大星期数
{
if (!used[j]) continue;
if (coins[j].numbers / used[j] < min_ans_tmp)
min_ans_tmp = coins[j].numbers / used[j];
}
for (j = pos; j < n; j++)
{
if (!used[j]) continue;
coins[j].numbers -= min_ans_tmp*used[j];
}
ans += min_ans_tmp;
}
printf("%d\n", ans);
}

Greedy:Allowance(POJ 3040)的更多相关文章
- 【贪心】Allowance POJ 3040
题目链接:http://poj.org/problem?id=3040 题目大意:你有n种不同面值的硬币,面值为vi的有bi个."硬币的面额均匀地分配下一个更大的面额",即下一个更 ...
- POJ 3040 Allowance【贪心】
POJ 3040 题意: 给奶牛发工资,每周至少 C 元.约翰手头上有面值V_i的硬币B_i个,这些硬币的最小公约数为硬币的最小面值.求最多能发几周? 分析: 贪心策略是使多发的面额最小(最优解).分 ...
- poj 3040 Allowance
Allowance Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 1842 Accepted: 763 Descript ...
- 【POJ - 3040】Allowance(贪心)
Allowance 原文是English,这里就放Chinese了 Descriptions: 作为创纪录的牛奶生产的奖励,农场主约翰决定开始给Bessie奶牛一个小的每周津贴.FJ有一套硬币N种(1 ...
- POJ 3040 Allowance 贪心
这题目的贪心思路还是有一点细节问题的. 还没有证明,据说是因为题目给的条件是每个价格是比它小的价格的倍数才能这么贪心的. 思路如下: 假设要给奶牛的钱为C 1)从大面值到小面值一次拿钱,能拿多少拿多少 ...
- Greedy:Subsequence(POJ 3061)
和最短序列 题目大意:找出一个序列中比至少和S相等的最短子序列(连续的) 本来这道题可以二分法来做复杂度O(NlogN),也可以用一个类似于游标卡尺的方法O(N)来做 先来讲游标卡尺法: 因为子序 ...
- Greedy:Stripes(POJ 1826)
新生物 题目大意:给你一堆数,两两结合,答案为2*sqrt(x1*x2),问组合成一个数时,最小的量? 超级无敌大水题,排序或者用堆都可以,反正就是优先组合大的,让根号一直把大数开根降低整体的大小 # ...
- Greedy:Packets(POJ 1017)
装箱问题1.0 题目大意:就是一个工厂制造的产品都是正方形的,有1*1,2*2,3*3,4*4,5*5,6*6,高度都是h,现在要包装这些物品,只能用6*6*h的包装去装,问你怎么装才能使箱子打到最小 ...
- POJ 3040 贪心
贪心好题 ---. 思路: 从大到小凑C 如果不够 再从小到大补满(超过)C //By SiriusRen #include <cstdio> #include <cstring&g ...
随机推荐
- 直接运行可执行文件linux终端一闪而过
运行elasticsearch的时候进入bin目录,ela 然后tab提示的内容中没有e..s..,很奇怪,然后我直接双击运行es,终端一闪而过,我就手动打开终端, ./elasticsearch 这 ...
- DataSet筛选数据然后添加到新的DataSet中引发的一系列血案
直入代码: var ds2 = new DataSet(); ) { ].Select(" usertype <> 'UU'"); ) { DataTable tmp ...
- 洛谷P1993 小 K 的农场
题目描述 小 K 在 Minecraft 里面建立很多很多的农场,总共 n 个,以至于他自己都忘记了每个 农场中种植作物的具体数量了,他只记得一些含糊的信息(共 m 个),以下列三种形式描 述: 农场 ...
- [NOIP2011] 提高组 洛谷P1003 铺地毯
题目描述 为了准备一个独特的颁奖典礼,组织者在会场的一片矩形区域(可看做是平面直角坐标系的第一象限)铺上一些矩形地毯.一共有 n 张地毯,编号从 1 到n .现在将这些地毯按照编号从小到大的顺序平行于 ...
- 锋利的jQuery-6--序列化函数serialize()和serializeArray()在表单提交中的作用
在通过jQuery ajax提交表单的时候,通常用下边的方法获取表单内容. var form = 'add-account-form'; //表单id $('#' + form).submit(fun ...
- 新浪微博客户端(5)-自定义UISearchBar
iOS自带的UISearchBar有很多限制,我们可以使用UITextField做出一个类似于SearchBar的效果. //===================================== ...
- QQ 腾讯QQ(简称“QQ”)是腾讯公司开发的一款基于Internet的即时通信(IM)软件
QQ 编辑 腾讯QQ(简称“QQ”)是腾讯公司开发的一款基于Internet的即时通信(IM)软件.腾讯QQ支持在线聊天.视频通话.点对点断点续传文件.共享文件.网络硬盘.自定义面板.QQ邮箱等多种功 ...
- linux 的useradd 命令的p选项
linux 的useradd 命令的p选项 错误用法: #useradd gaojian -p gaojian # ...
- explicit构造函数
explicit构造函数 Explicit Constructors(显式构造函数)收藏 按照默认规定,只有一个参数的构造函数也定义了一个隐式转换,将该构造函数对应数据类型的数据转换为该类对象,如下面 ...
- 深入浅出 - Android系统移植与平台开发(五)- 编译Android源码(转)
2.3编译Android源码 Android源码体积非常庞大,由Dalvik虚拟机.Linux内核.编译系统.框架代码.Android定制C库.测试套件.系统应用程序等部分组成,在编译Android源 ...