您的位置:首页 > 其它

poj 3040 Allowance (贪心)

2014-01-09 20:32 288 查看
题意:有各种不同面值xi的硬币ci个,问要给别人发工资(一个星期的工资至少为c)

最多能发给它多少个星期。(小硬币的面值能整除大硬币)

分析:

1、按面值从大到小排序,如果能选大的尽量选大的,只要不超过c就能放多少放多少。

最后再从小的开始找放进去超额的。

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;

struct money
{
    int v,cnt;
}coin[25];
int need[25];

bool cmp(money x,money y)
{
    return x.v>y.v;
}

int main()
{
    int n,c,ans;
    while(scanf("%d%d",&n,&c)!=EOF)
    {
        for(int i=1;i<=n;i++)
            scanf("%d%d",&coin[i].v,&coin[i].cnt);
        sort(coin+1,coin+n+1,cmp);
        ans=0;
        while(1)
        {
            memset(need,0,sizeof(need));
            int sum=c;
            for(int i=1;i<=n;i++)
            {
                int tmp=sum/coin[i].v;
                need[i]=min(coin[i].cnt,tmp);
                sum-=coin[i].v*need[i];
            }
            if(sum>0)
            {
                for(int i=n;i>=1;i--)
                {
                    if(coin[i].cnt && coin[i].v>=sum)
                    {
                        need[i]++;
                        sum=0;
                        break;
                    }
                }
            }
            if(sum>0) break;
            int s=0x3f3f3f3f;
            for(int i=1;i<=n;i++)
            {
                if(need[i])
                    s=min(s,coin[i].cnt/need[i]);
            }
            ans+=s;
            for(int i=1;i<=n;i++)
            {
                if(need[i])
                    coin[i].cnt-=need[i]*s;
            }
        }
        printf("%d\n",ans);
    }
    return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: