零用钱
时间限制: 1 Sec 内存限制: 128 MB[ 提交][ 状态][ 讨论版]
题目描述
作為创造產奶纪录的回报,Farmer John决定开始每个星期给Bessie一点零花钱。 FJ有一些硬币,一共有N (1 < = N < = 20)种不同的面额。每一个面额都能整除所有比它大的面额。 他想用给定的硬币的集合,每个星期至少给Bessie某个零花钱的数目C (1 < = C < = 100000000)。请帮他计算他最多能支付多少个星期的零花钱。
输入
* 第一行: 两个由空格隔开的整数: N 和 C * 第2到第N+1行: 每一行有两个整数表示一个面额的硬币:硬币面额V (1 < = V < = 100,000,000)和Farmer John拥有的该面额的硬币数B (1 < = B < = 1,000,000).
输出
* 第一行: 一个单独的整数,表示Farmer John最多能给Bessie支付多少个星期至少為C的零用钱。
样例输入
3 6
10 1
1 100
5 120
样例输出
111
提示
FJ想要每个星期给Bessie六美分。他有100个1美分硬币,120个5美分硬币,和一个10美分硬币。 FJ可以在一个星期超额付给Bessie一个10美分硬币。然后接下来的10个星期每星期付给 Bessie两个5美分硬币。最后100个星期每星期付给Bessie一个1美分硬币跟一个5美分硬 币。
# include<stdio.h>
# include<algorithm>
using namespace std;
struct node{
int x;
int m;
}a[25];
bool cmp(node a,node b) //从小到大排
{
return a.x<b.x;
}
int main(){
int N,C;
scanf("%d %d",&N,&C);
for(int i=0;i<N;i++)
scanf("%d %d",&a[i].x,&a[i].m);
sort(a,a+N,cmp);
int k,count=0; //k 保存的是排序后的面额小于C中的最大面额,count计数
for(k=N-1;k>=0;k--) // 若面额大于C直接加上 count
{
if(a[k].x>=C)
{
count+=a[k].m;
}
else break;
}
int floag=1;
while(floag)
{
floag=0;
int t=C; // 每次将C值赋给t
for(int i=k;i>=0;i--) //先尽量减去最大面额
{
while(t>a[i].x&&a[i].m>0)
{
t-=a[i].x;
a[i].m--;
}
}
for(int i=0;i<=k;i++) //再减去小的
{
while(t>0&&a[i].m>0)
{
t-=a[i].x;
a[i].m--;
}
}
if(t<=0) {
floag=1;
count++;
}
}
printf("%d\n",count);
return 0;
}