poj3040 发工资(贪心)
题目大意:给一个人发工资,给出不同数量不同面额,(大面额一定是小面额的倍数),问最多能发几天,(每天实发工资>=应发工资)。
思路:首先,将大于等于c的面额的钱直接每个星期给奶牛一张,将面额大于等于c的前去除。然后从大到小开始选择,要选择的金额尽可能的接近c,如果刚好能够凑足c就作为当前的一种方案,如果不能凑足c那就再从小的开始选,要选出一种的总额不少于c但尽量接近c作为当前的方案,然后计算如果按照如此方案最多可以给奶牛多少周,然后按照相同的方法再选方案,一直选到选择的金额不能凑足c为止。
为什么这样做是对的呢?
题目中说大面值一定是小面值的倍数,所以,如果一个数字可以用大面值凑,那必定可以用小面值凑,也就是说,小面值的功能比大面值强。我们在能选择大面值的时候,尽量选择大面值。在这个过程中我们一直保证m<=c,但如果我们不能使m<=c,即即便我们用了最小的面额也会超值,那就只能浪费超过的这一部分了,并且此时浪费的是最少的。(如果先选小的再选大的,浪费的肯定大于等于此时的情况)
代码。
#include<iostream>
#include<algorithm>
#include<cstdlib>
#include<sstream>
#include<cstring>
#include<bitset>
#include<cstdio>
#include<string>
#include<deque>
#include<stack>
#include<cmath>
#include<queue>
#include<set>
#include<map>
#define INF 0x3f3f3f3f
#define CLR(x,y) memset(x,y,sizeof(x))
#define LC(x) (x<<1)
#define RC(x) ((x<<1)+1)
#define MID(x,y) ((x+y)>>1)
using namespace std;
typedef long long ll;
struct dian {
int val,to;
} a[30];
bool cmp(dian a,dian b) {
return a.val<b.val;
}
int make[30];
int main() {
int n,c;
cin>>n>>c;
for(int i=1; i<=n; i++) {
cin>>a[i].val>>a[i].to;
}
sort(a+1,a+1+n,cmp);
int ans=0;
for(int i=n; i>0; i--) {
if(a[i].val>=c) {
ans+=a[i].to;
n--;
} else break;
}
bool flag;
while(1) {
flag=false;
memset(make,0,sizeof(make));//make表示 某一种货币在一种工资组合中的使用次数
int tepc=c;
int i;
for(i=n; i>0; i--) {
if(a[i].to) {
int m,num;
num=tepc/a[i].val;
m=min(num,a[i].to);//尽可能的多用,但不能超过总数
tepc-=m*a[i].val;
make[i]=m;
if(tepc==0) { //此处只会>=0
flag=true;
break;
}
}
}
if(tepc>0) {
for(i=1; i<=n; i++) {
if(a[i].to>make[i]) {//make里面存的是当前这一轮用过的 除了用过的 还有剩下的 才可以用这种货币
while(make[i]<a[i].to) {
tepc-=a[i].val;
make[i]++;
if(tepc<0) {//此处不会=0 因为=0的情况上面已经排除掉了
flag=true;
break;
}
}
}
if(flag)break;
}
}
if (!flag) break;
int cnt=0x3f3f3f3f;
for(int i=1;i<=n;i++){
if(make[i])
cnt=min(cnt,a[i].to/make[i]);//最小的组合
}
ans+=cnt;
for(int i=1;i<=n;i++){
a[i].to-=make[i]*cnt;
}
}
cout<<ans<<endl;
}
| Time Limit: 1000MS | Memory Limit: 65536K | |
| Total Submissions: 5167 | Accepted: 2032 |
Description
Input
* Lines 2..N+1: Each line corresponds to a denomination of coin and contains two integers: the value V (1 <= V <= 100,000,000) of the denomination, and the number of coins B (1 <= B <= 1,000,000) of this denomation in Farmer John's possession.
Output
Sample Input
3 6
10 1
1 100
5 120
Sample Output
111
Hint
FJ would like to pay Bessie 6 cents per week. He has 100 1-cent coins,120 5-cent coins, and 1 10-cent coin.
OUTPUT DETAILS:
FJ can overpay Bessie with the one 10-cent coin for 1 week, then pay Bessie two 5-cent coins for 10 weeks and then pay Bessie one 1-cent coin and one 5-cent coin for 100 weeks.
poj3040 发工资(贪心)的更多相关文章
- (简单贪心) 发工资咯:) hdu2021
发工资咯:) Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Subm ...
- ACM_发工资(简单贪心)
发工资咯: Time Limit: 2000/1000ms (Java/Others) Problem Description: 作为广财大的老师,最盼望的日子就是每月的8号了,因为这一天是发工资的日 ...
- 贪心--HDU 2021 发工资咯
Description 作为杭电的老师,最盼望的日子就是每月的8号了,因为这一天是发工资的日子,养家糊口就靠它了,呵呵,但是对于学校财务处的工作人员来说,这一天则是很忙碌的一天,财务处的小胡老师最近就 ...
- POJ3040给奶牛发工资
题意: 有n种硬币,每种硬币有mi个,然后让你给奶牛发工资,每周发至少c元(就是不找零钱的意思)然后问你能发几周?(硬币之间都是倍数关系) 思路: 这个题目做了两天,丢脸,看完 ...
- HDU 2021 发工资咯:)(最水贪心)
传送门: http://acm.hdu.edu.cn/showproblem.php?pid=2021 发工资咯:) Time Limit: 2000/1000 MS (Java/Others) ...
- HDOJ2021发工资咯:)
发工资咯:) Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Subm ...
- HDOJ 2021 发工资咯:)(利用了一种取余的思想)
Problem Description 作为杭电的老师,最盼望的日子就是每月的8号了,因为这一天是发工资的日子,养家糊口就靠它了,呵呵 但是对于学校财务处的工作人员来说,这一天则是很忙碌的一天,财务处 ...
- python实现发工资脚本
好开心啊,在旁边大神的帮助下,终于实现了发工资的python脚本,之前用shell写的老出错,刚才测试,发80个人工资详情,妥妥的,代码如下: from email.mime.multipart im ...
- HDU 2021 发工资咯:)
http://acm.hdu.edu.cn/showproblem.php?pid=2021 Problem Description 作为杭电的老师,最盼望的日子就是每月的8号了,因为这一天是发工资的 ...
随机推荐
- js调试的一点小知识
1.如果想要js代码被XHTML和HTML解析,就可以使用如下方式 <script type="text/javascript"> //<![CDATA[ fun ...
- 理解和正确使用Java中的断言(assert)
一.语法形式: Java2在1.4中新增了一个关键字:assert.在程序开发过程中使用它创建一个断言(assertion),它的语法形式有如下所示的两种形式:1.assert conditio ...
- css中的hack
1.什么是CSS hack? CSS hack是通过在CSS样式中加入一些特殊的符号,让不同的浏览器识别不同的符号(什么样的浏览器识别什么样的符号是有标准的,CSS hack就是让你记住这个标准),以 ...
- Replace Pioneer注册方法
Replace Pioneer注册方法 Replace Pioneer过期后,会弹出一个注册(Registration)窗口,其中有一个试用选项(Trial License),点击Trial Lice ...
- c#基础;初步学习循环语句
循环语句就是 在满足循环条件的情况下会有顺序的执行循环体 循环语句:for : while : foreach:三种. 循环语句 必须具备四要素:初始条件.循环条件.循环体.状 ...
- C++读入整行字符串的方法
string s; getline(cin,s); cout<<s<<endl; ]; scanf("%[^\n]%*c",s); printf(" ...
- (转)Linux网络协议栈(三)——网络设备(1)
网络设备(network device)是内核对网络适配器(硬件)的抽象与封装,并为各个协议实例提供统一的接口,它是硬件与内核的接口,它有两个特征:(1) 作为基于硬件的网络适配器与基于软件的协 ...
- css选择器的一些说明
标签选择器.ID选择器.类选择器 这三个很简单,没啥可说的. 子选择器得说一下. <ul class="food"> <li>水果 &l ...
- C++面试笔记--单链表
1.编程实现单链表删除节点. 解析:如果删除的是头节点,如下图: 则把head指针指向头节点的下一个节点.同时free p1,如下图所示: 如果删除的是中间节点,如下图所示: 则用p2的n ...
- Linux系统命令Top/free的使用及参数详解
1.作用 top命令用来显示执行中的程序进程,使用权限是所有用户. 2.格式 top [-] [d delay] [q] [c] [S] [s] [i] [n] 3.主要参数 d:指定更新的间隔,以秒 ...