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 ...
随机推荐
- spring - ioc和aop
1.程序中为什么会用到spring的ioc和aop 2.什么是IOC,AOP,以及使用它们的好处,即详细回答了第一个问题 3.原理 关于1: a:我们平常使用对象的时候,一般都是直接使用关键字类new ...
- BZOJ-1477 青蛙的约会 拓展欧几里德
充权限之前做的...才来交 1477: 青蛙的约会 Time Limit: 2 Sec Memory Limit: 64 MB Submit: 369 Solved: 233 [Submit][Sta ...
- Codeforces 650C Table Compression
传送门 time limit per test 4 seconds memory limit per test 256 megabytes input standard input output st ...
- jQueryEasyUI DateBox的基本使用
http://www.cnblogs.com/libingql/archive/2011/09/25/2189977.html 1.基本用法 代码: 1 2 3 4 5 6 7 8 9 10 11 1 ...
- MySQL 中 where id in (1,2,3,4,...) 的效率问题讨论
MySQL ACMAIN_CHM06-26 16:36 等级 84次回复 [求证&散分]MySQL 中 where id in (1,2,3,4,...) 的效率问题讨论 庆祝本月大版得 ...
- 伪分布模式下执行wordcount实例时报错解决办法
问题1.不能分配内存,错误提示如下: FAILEDjava.lang.RuntimeException: Error while running command to get file permiss ...
- [pdf.js]预览pdf时,中文名称乱码的问题
在项目中使用了pdf.js的方式预览pdf,但针对中文名称的时候会出现乱码,导致找不到该文件而出现错误. 解决办法 <script src="viewer.js" chars ...
- C语言中strstr函数
头文件:#include <string.h> strstr()函数用来检索子串在字符串中首次出现的位置,其原型为: char *strstr( char *str, char * ...
- 我的css释疑-float line-height inline-block vertical-align
markdown的图片和链接格式相类似: [链接文字/图片的alt text] (链接地址/ 图片的地址), 只是图片要在前面加上感叹号! 当内容中含有图片的时候,如果图片的高度大于行高,则含有图片 ...
- POJ 3267 The Cow Lexicon
又见面了,还是原来的配方,还是熟悉的DP....直接秒了... The Cow Lexicon Time Limit: 2000MS Memory Limit: 65536K Total Submis ...