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; }