题意:
要付给某人一周的工资c,现在给出一共有的钱,以及每种钱的数量。问能付多少周。
思路:
至今不知道如何理解这种方法,暂时是这么理解的:给工资的时候可以多给点,但是不能少给,
- 比c大的钱直接给(很有钱的样子)
- 然后再从大到小给钱若找不开则从小到大找零钱给。
不过还是有一个好的思路,就是可以用num记录每一种方案所花的钱数,然后以倍数的关系进行计算。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
class Node
{
public:
int v,b;
}corn[30];
int cmp(Node a,Node b)
{
return a.v < b.v;
}
int n,c;
int num[30];
int main()
{
//freopen("in.txt","r",stdin);
while(scanf("%d%d",&n,&c) != EOF){
for(int i = 0;i < n; i++){
scanf("%d%d",&corn[i].v,&corn[i].b);
}
sort(corn,corn+n,cmp);
int ans = 0;
for(int i = n - 1;i >= 0; i--){
if(corn[i].v > c){
ans += corn[i].b;
corn[i].b = 0;
}
}
while(true){
memset(num,0,sizeof(num));
int flag = false;
int temp = c;
for(int i = n - 1;i >= 0; i--){
if(corn[i].b){
int k = temp/corn[i].v;
k = min(k,corn[i].b);
temp -= corn[i].v*k;
num[i] = k;
if(temp == 0){
flag = true;
break;
}
}
}
if(temp > 0){
for(int i = 0;i < n; i++){
while(corn[i].b > num[i]){
temp -= corn[i].v;
num[i]++;
if(temp <= 0){
flag = true;
break;
}
}
if(flag)
break;
}
}
if(!flag)
break;
int m = 0x3f3f3f3f;
for(int i = 0;i < n; i++){
if(num[i]){
m = min(m,corn[i].b/num[i]);
}
}
ans += m;
for(int i = 0;i < n; i++){
if(num[i]){
corn[i].b -= num[i]*m;
}
}
}
printf("%d\n",ans);
}
return 0;
}