【tyvj1032】零用钱 深搜+贪心

来源:互联网 发布:域名投资人联系 编辑:程序博客网 时间:2024/05/20 13:39
  • 背景

    • USACO OCT09 7TH
  • 描述

    -作為创造產奶纪录的回报,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美分硬
    币。

tyvj1032

很容易想到的贪心:优先选最大的,对于剩下的钱总是选最大的但不超过c,最后用小的填上或超过c
总之就是不要让他花超太多

我打的dfs,实测证明tyvj评测机还是可以的hhh

代码内附第四个点的数据……
代码:

#include<cstdio>#include<iostream>#include<cstring>#include<algorithm>using namespace std;const int size=10010;struct haha{    int v,num;}l[size],ll[size];bool cmp(haha a,haha b){    return a.v>b.v;}int n,c,ans=0;int temp[size];int div(int v){    int tot=0;    for(int i=1;i<=n;i++)     {        if(l[i].num) temp[++tot]=l[i].v;    }    int s=0,t=tot;    while(t-s>1)    {        int mid=(s+t)>>1;        if(temp[mid]<v) t=mid;        else s=mid;    }     for(int i=1;i<=n;i++)    {        if(l[i].v==temp[t]) return i;    }}bool dfs(int d){    if(d>=c)     {        ans++;        return true;    }    for(int i=div(c-d);i<=n;i++)    {        if(l[i].num)        {            int k=min(l[i].num,(c-d)/l[i].v);            if(k==0) k=1;            l[i].num-=k;            if(dfs(d+k*l[i].v)) return true;            l[i].num+=k;         }    }    return false;}int main(){    scanf("%d%d",&n,&c);    for(int i=1;i<=n;i++)    {        scanf("%d%d",&ll[i].v,&ll[i].num);    }    sort(ll+1,ll+1+n,cmp);    int tot=0;    for(int i=1;i<=n;i++)    {        if(ll[i].v>=c) ans+=ll[i].num;        else l[++tot]=ll[i];    }    n=tot;    sort(l+1,l+1+n,cmp);    while(dfs(0));    //for(int i=1;i<=n;i++) cout<<l[i].v<<" "<<l[i].num<<endl;     printf("%d",ans);    return 0; }/*3 6 10 1 1 1 5 2120 10000000067108864 100000033554432 100000016777216 10000008388608 10000004194304 10000002097152 10000001048576 1000000524288 1000000262144 1000000131072 100000065536 100000032768 100000016384 10000008192 10000004096 10000002048 10000001024 1000000512 1000000256 1000000128 1000000*/
0 0