博客园 首页 私信博主 显示目录 隐藏目录 管理 动画

bzoj:1685 [Usaco2005 Oct]Allowance 津贴

Description

As a reward for record milk production, Farmer John has decided to start paying Bessie the cow a small weekly allowance. FJ has a set of coins in N (1 <= N <= 20) different denominations, where each denomination of coin evenly divides the next-larger denomination (e.g., 1 cent coins, 5 cent coins, 10 cent coins, and 50 cent coins). Using the given set of coins, he would like to pay Bessie at least some given amount of money C (1 <= C <= 100,000,000) every week. Please help him compute the maximum number of weeks he can pay Bessie.

作为对勤勤恳恳工作的贝茜的奖励,约翰已经决定开始支付贝茜一个小的每周津贴.  约翰有n(1≤N≤20)种币值的硬币,面值小的硬币总能整除面值较大的硬币.比如说,币值有如下几种:1美分,5美分,10美分,50美分…..
    利用给定的这些硬币,他将要每周付给贝茜一定金额的津贴C(1≤C≤10^8).
    请帮他计算出他最多能给贝茜发几周的津贴.

Input

    第1行:2个用空格隔开的整数n和C.
    第2到n+1行:每行两个整数表示一种币值的硬币.第一个整数V(I≤y≤10^8),表示币值.
第二个整数B(1≤B≤10^6),表示约翰拥有的这种硬币的个数.

Output

    一个整数,表示约翰付给贝茜津贴得最多的周数.

Sample Input

3 6
10 1
1 1 00
5 1 20

Sample Output

111
样例说明
约翰想要每周付给贝茜6美分.他有1个10美分的硬币、100个1美分的硬币、120个5美分的硬币.约翰可以第一周付给贝茜一个10美分的硬币,接着的10周每周付给贝茜2个5芙分硬币,接下来的100周每周付给贝茜一个1美分的硬币和1个5美分的硬币.共计111周.

 

 

 

贪心每次从最大的硬币拿,能拿多少拿多少,最后还不够就找个最小的硬币扔上去。由于数据实在太水,不开long long都可以过……

#include<cstdio>
#include<algorithm>
using namespace std;
struct na{
    int v,l;
};
int n,m,pos[20];
na o[20];
int ans=0;
bool cmp(na a,na b){
    return a.v>b.v;
}
int main(){
    scanf("%d%d",&n,&m);
    for (int i=0;i<n;i++){
        scanf("%d%d",&o[i].v,&o[i].l);
        if (o[i].v>=m) ans+=o[i].l,i--,n--;
    }
    sort(o,o+n,cmp);
    int k,num;
    do{
        k=0;num=1e7;
        for (int i=0;i<n;i++)
        if (o[i].l){
            int xx=min((m-k)/o[i].v,o[i].l);
            k+=xx*o[i].v;
            if (xx!=0) num=min(num,o[i].l/xx);
            pos[i]=xx;
        }else pos[i]=0;
        if (k<m)
        for (int i=n-1;i>=0;i--)
        if (o[i].l&&o[i].v>=m-k){
            pos[i]++;
            num=min(num,o[i].l/pos[i]);
            k+=o[i].v;
            n=i+1;
            break;
        }
        if (k<m) break;
        ans+=num;
        for (int i=0;i<n;i++) o[i].l-=num*pos[i];
    }while(num);
    printf("%d\n",ans);
}

 

posted @ 2015-12-01 14:27  swm_sxt  阅读(417)  评论(1编辑  收藏  举报