ACM山东大学2018 校赛i

A Love Story

Description

In order to make the girlfriend happy,CZY decided to send flowers to CM every week. CZY has some coins, a total of N (1 <= N <= 20) different denominations. Every denomination can divide all the denominations that are bigger than it. He wants to use this set of coins to buy flowers per week. The cost of the flowers is at least C(1 <= C <= 100000000), and the shop won't give change. Please help him figure out how many weeks he can send flowers to his girlfriend.

Input

There are multiple sets of input and output,Each set contains:

Line 1: two integers separated by space: N and C  

second to line N+1: each row has two integers representing a denomination of coins: coin denomination V (1 <= V <= 100000000) and the number of coins of that denomination that CZY has, B (1 <= B <= 1000000).

Output

A single integer, means that CZY can send flowers at most weeks.

Sample Input 1 

3 6
10 1
1 100
5 120

Sample Output 1

111

Hint

CZY can pay a 10 cent coin in a week. Then he pays two 5 cent coins every week for the next 10 weeks. In the last 100 weeks, he pays a 1 cent coin and a 5 cent coin.



#include<iostream>

#include<algorithm>
#include<string.h>
#include<cstdio>
using namespace std;
//学姐的代码  第一个优先取最大 然后找出加和小于等于C的数%%%%
struct node{
    int x,y;
};
bool cmp(node a,node b)
{
    return a.x>b.x;
}
node coin[30];
int n,c,tot;
long long ans=0;


int dfs(int d)
{
    if(d>=c) {ans++;return 1;}///加和比大就直接加一跳出,
    int id=0;
    for(;id<tot;id++)
    {
        if(coin[id].x+d<=c&&coin[id].y)///去了个的等号  if(coin[id].x+d<=c&&coin[id].y)
            break;//尽量加小的或者正好的
    }
    while(id>0&&!coin[id].y)// 如果找不到更小的及后面都为0 就只能去取大的 找到前面一个非空的
    {
       id--;
    }
    for(int i=id;i<tot;i++)
    {
         if(coin[i].y)//还有
        {
            int k=min(coin[i].y,(c-d)/coin[i].x);//min 个数  差值/面值
            if(k==0) k=1;//也是尽可能的使用大的
            coin[i].y-=k;
            if(dfs(d+k*coin[i].x)) return true;
            coin[i].y+=k;//回溯
        }
     }
     return false;




}
int main()
{
    while(scanf("%d%d",&n,&c)!=EOF)
    {
        ans=0;
        tot=0;
        for(int i=0;i<n;i++)
        {
            int temp1,temp2;
            scanf("%d%d",&temp1,&temp2);
            if(temp1>=c)
                ans+=temp2;
            else
            {
                coin[tot].x=temp1;
                coin[tot++].y=temp2;
            }


        }
        sort(coin,coin+tot,cmp);
        while(dfs(0));
        printf("%d\n",ans);




    }


}


%%%%%%%%%%%%%%%%%%%%%%%%%%%%详情看注释




挂一个菜鸡的代码,样例过了,结果死活过不去

#include<iostream>
#include<algorithm>
#include<string.h>
#include<cstdio>
using namespace std;
typedef long long ll;
typedef struct
{
    long long  a,b;
} node;

ll temp1,temp2,i,j,id,ans, c,n,count1=0;
node a[25];

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

}


bool dfs(int now)
{
    if(now>=n)
    {
        ans++;
        return true;
    }
    for(id=0; id<c; ++id)
    {
        if(now+a[id].a<=n&&a[id].b) //找出目前还行的 在不超C的情况下加上这个数
        {
            break;
        }
    }//去掉超出范围的

    while(!a[id].b&&id>0)//找bu到小鱼C的
    {
        --id;
    }
    for(; id<c; ++id)
    {
        if(a[id].b)//有可能全空的时候bug
        {
            int k=min(a[id].b,(n-now)/a[id].a);//去最少的 如果不够的话就全用上
            if(k==0)
            {
                k=1;
            }
            a[id].b-=k;
            if(dfs(now+k*a[id].a))
                return true;
            a[id].b+=k;
        }


    }
    return false;//都无法执行

}
int main()
{

//freopen("Data.txt","r",stdin);
    while(cin>>c>>n)
    {
        ans=0;
        for(i=0; i<c; ++i)
        {
            cin>>a[i].a>>a[i].b;

        }
        sort(a,a+c,cmp);
        for(id=0; id<c; ++id)
        {
            if(a[id].a>=n)
            {
                ans+=a[id].b;
                a[id].b=0;

                continue;
            }break;
        }//去掉超出范围的
        while(dfs(0));
        cout<<ans<<endl;

    }

    return 0;
}
上边的这个代码在定义结构体数组时错了,改了以后就A了
#include<iostream>
#include<algorithm>
#include<string.h>
#include<cstdio>
using namespace std;
typedef long long ll;
struct node{
    long long  a,b;
} ;

ll temp1,temp2,i,j,id,ans, c,n,count1=0;
    node a[10000];

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

}


bool dfs(int now)
{
    if(now>=n)
    {
        ans++;
        return true;
    }
    for(id=0; id<c; ++id)
    {
        if(now+a[id].a<=n&&a[id].b) //找出目前还行的 在不超C的情况下加上这个数
        {
            break;
        }
    }//去掉超出范围的

    while(!a[id].b&&id>0)//找bu到小鱼C的
    {
        --id;
    }
    for(; id<c; ++id)
    {
        if(a[id].b)//有可能全空的时候bug
        {
            int k=min(a[id].b,(n-now)/a[id].a);//去最少的 如果不够的话就全用上
            if(k==0)
            {
                k=1;
            }
            a[id].b-=k;
            if(dfs(now+k*a[id].a))
                return true;
            a[id].b+=k;
        }


    }
    return false;//都无法执行

}
int main()
{

//freopen("Data.txt","r",stdin);
    while(cin>>c>>n)
    {
        ans=0;
        for(i=0; i<c; ++i)
        {
            cin>>a[i].a>>a[i].b;

        }
        sort(a,a+c,cmp);
        for(id=0; id<c; ++id)
        {
            if(a[id].a>=n)
            {
                ans+=a[id].b;
                a[id].b=0;

                continue;
            }break;
        }//去掉超出范围的
        while(dfs(0));
        cout<<ans<<endl;

    }

    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值