1. 程式人生 > >POJ3040--Allowance(貪心)

POJ3040--Allowance(貪心)

wan ack push second else sizeof div 把他 memset

http://poj.org/problem?id=3040

思路:

輸入時,如果有大於c的,直接把數量加到結果中,不把他加到數組中

把錢按面值排序

想取最大面額的錢,保證取到的錢小於等於c

然後取最小面額的錢

#include<iostream>
#include<vector>
#include<algorithm>
#include<string.h>
using namespace std;
int main(){
    int n,c;
    cin>>n>>c;
    int ans=0
; vector<pair<int,int> > v; for(int i=0;i<n;i++){ int a,b; cin>>a>>b; if(a>=c) ans+=b; else v.push_back(make_pair(a,b)); } int use[22]; sort(v.begin(),v.end()); while(true){
int money=0; memset(use,0,sizeof(use)); int flag=0;//1表示成立 0不成立 for(int i=v.size()-1;i>=0;i--){ if(v[i].second!=0){ int amount=(c-money)/v[i].first; int minn=min(amount,v[i].second); // v[i].second-=minn; 不能這樣取了就直接減到.因為可能目前這種取法,並不成立
money+=v[i].first*minn; use[i]=minn; if(money==c){ flag=1; break; } } } if(flag==0){ for(int j=0;j<v.size();j++){ if(v[j].second!=0&&v[j].second>use[j]){ int diff=c-money; int amount=diff/v[j].first; if(amount==0)//如果0,說明當前的差值小於c,所以只要再取一個,就可以大於c amount=1; int minn=min(amount,v[j].second); money+=v[j].first*minn; use[j]+=minn; if(money>=c){ flag=1; break; } } } } if(flag==1){ int minn=INT_MAX; for(int i=0;i<v.size();i++){ if(use[i]!=0){ minn=min(minn,v[i].second/use[i]); } } ans+=minn; for(int i=0;i<v.size();i++){ if(use[i]!=0){ v[i].second-=use[i]*minn; } } } else{ break; } } cout<<ans<<endl; return 0; }

POJ3040--Allowance(貪心)