题目链接
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;
}