Allowance POJ - 3040 贪心+模拟

题目链接
1 面值比c大的直接当一次
2 面值比C小的贪心求解, 先从大面值到小面值遍历,使得总和小于等于C,然后从小到到大遍历,使得总和大于等于C
参考博客

#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <iostream>
#include <cmath>
#include <vector>
#include <map>
#include <stack>
#include <queue>
using namespace std;
typedef long long ll;
const int MAX=0x3f3f3f3f;
const int N=25;
struct Coin{
	int v,num;
}coin[N];
int need[N];
bool cmp(Coin a,Coin b){
	return a.v<b.v;
} 
int main(){
	int n,c;
	cin>>n>>c;
	int ans=0,number=0;
	for(int i=0;i<n;i++){
		int a,b;
		cin>>a>>b;
		if(a>=c) ans+=b;
		else{ 
			coin[number].v=a;        //不是i,是number 
			coin[number++].num=b;
		}
	}
	sort(coin,coin+number,cmp);         
	while(1){
		int temp=c;
		for(int i=number-1;i>=0;i--){
			need[i]=min(coin[i].num,temp/coin[i].v);
			temp-=need[i]*coin[i].v;
			if(temp==0) break;
		}
		for(int i=0;i<number;i++){
			int d=min(coin[i].num-need[i],(temp+coin[i].v-1)/coin[i].v);
			need[i]+=d;
			temp-=d*coin[i].v;
		}
		if(temp>0) break;
		else{
			int t=MAX;
			for(int i=0;i<number;i++){
				if(need[i]!=0){             //不加判断会报错 
					t=min(t,coin[i].num/need[i]);
				}
			}
			for(int i=0;i<number;i++){
				coin[i].num-=t*need[i];
			}
			ans+=t;
		}
	}
	cout<<ans<<endl;
}
	
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值