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 ...
随机推荐
- BZOJ-1013 球形空间产生器sphere 高斯消元+数论推公式
1013: [JSOI2008]球形空间产生器sphere Time Limit: 1 Sec Memory Limit: 162 MB Submit: 3662 Solved: 1910 [Subm ...
- 基于SVD的推荐算法
首先每行减去每列的均值,然后svd分解,得到USV,然后US代表用户矩阵u,SV代表项目矩阵v,那么预测评分为用户均值加上uv. 降维方法扩展性好,不过降维导致信息损失,而且与数据及相关,高维情况下效 ...
- 自动打包iOS项目
基于Lexrus的博文iOS-makefile,本文对自动打包涉及到的操作步骤以及理论基础进行了适当的补充. 请在阅读本文前先阅读<iOS makefile>.文章地址:http: ...
- 一个共通的viewModel搞定所有的编辑页面-经典ERP录入页面(easyui + knockoutjs + mvc4.0)
http://www.cnblogs.com/xqin/archive/2013/06/06/3120887.html 前言 我写代码喜欢提取一些共通的东西出来,之前的一篇博客中说了如何用一个共通的v ...
- day4作业之信息表
实在是太low了,终究是自己写的,记录下 #!/usr/bin/env python # coding=utf8 import os, re #这里我把查询这块分为3个函数了,纠结了很久是放一起还是分 ...
- C# 设置开机自动启动(注册表方式)
.NET技术交流群 199281001 .欢迎加入. using System; using System.Collections.Generic; using System.Linq; using ...
- Vim常用操作(1)-常用指令
1.清空文件内容 Normal模式下,先输入"gg",将光标定位到文件首,然后输入"dG",文件就被清空了.当然也可以直接输入"ggdG".
- MapReduce使用JobControl管理实例
import java.io.IOException; import java.util.StringTokenizer; import org.apache.hadoop.fs.Path; impo ...
- Object学习笔记
<script type="text/javascript"> function forEach(o){ var html =""; for(var ...
- jsp 变量和方法的声明 Java程序片 HTML注释 JSP注释
<%!...%> 声明变量和方法 <%!...%>之中的变量为JSP页面的成员变量,当多个线程访问本页面时,多个线程共享此变量. <%@ page contentType ...