计蒜客 零花钱

作為创造產奶纪录的回报,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的零用钱。

FJ想要每个星期给Bessie六美分。他有100个1美分硬币,120个5美分硬币,和一个10美分硬币。 FJ可以在一个星期超额付给Bessie一个10美分硬币。然后接下来的10个星期每星期付给 Bessie两个5美分硬币。最后100个星期每星期付给Bessie一个1美分硬币跟一个5美分硬 币。

样例输入

3 6
10 1
1 100
5 120

样例输出

111
题解:面额从大往小排。只要比C小就用面额小的一点点加。直到超过或相等,则ans++


#include<bits/stdc++.h>
using namespace std;

struct node{
    long num;
    long many;
}a[21];

bool cmp(node a,node b){
    return a.num>b.num;
}

int main()
{
    long c;
    long n,ans=0;
    cin>>n>>c;
    for(int i=0; i<n; i++)
    {
        cin>>a[i].num>>a[i].many;
    }
    sort(a,a+n,cmp);//将面额大的排前面
    while(1){
        int f=c;
        for(int i=0; i<n; i++)//找出第一个比C小的数
            while(a[i].many&&f-a[i].num>0)
                a[i].many--,f-=a[i].num;
        for(int i=n-1; i>=0; i--)//用小的数一点一点加上前面找出的数直到比C大或等
            while(a[i].many&&f>0)
                a[i].many--,f-=a[i].num;
        if(f<=0)
            ans++;
        else
            break;
    }
    cout<<ans;
    return 0;
}


阅读更多
个人分类: 贪心
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

关闭
关闭
关闭