杭电1085

这里写链接内容

Holding Bin-Laden Captive!
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 13861 Accepted Submission(s): 6230

Problem Description
We all know that Bin-Laden is a notorious terrorist, and he has disappeared for a long time. But recently, it is reported that he hides in Hang Zhou of China!
“Oh, God! How terrible! ”

Don’t be so afraid, guys. Although he hides in a cave of Hang Zhou, he dares not to go out. Laden is so bored recent years that he fling himself into some math problems, and he said that if anyone can solve his problem, he will give himself up!
Ha-ha! Obviously, Laden is too proud of his intelligence! But, what is his problem?
“Given some Chinese Coins (硬币) (three kinds– 1, 2, 5), and their number is num_1, num_2 and num_5 respectively, please output the minimum value that you cannot pay with given coins.”
You, super ACMer, should solve the problem easily, and don’t forget to take $25000000 from Bush!

Input

Output
Output the minimum positive value that one cannot pay with given coins, one line for one case.

Sample Input
1 1 3
0 0 0

Sample Output
4

题意:给定三中硬币,面值分别为1,2,5,并且给定三种硬币的数量分别为num_1,num_2,num_5,然后让求解这些硬币所不能组成的最小的面额是多少,例如给定的例子,面值为1的硬币为1枚,面值为2的硬币为1枚,面值为5的硬币为3枚,则可以组成的面值有1,2,3,5……所以,不能组成的最小面额为4。这就是一道母函数的问题,但是这里并不是求组合数,所以,不需要int行的数组来记录组合数,只需要true和false来标示是否能表示该面值就可以了。当然用int记录组合数也可以,但要注意,因为组合量非常大,要注意溢出的情况,我试了一下可以,判断大于0的时候置1就能过。

代码:

# include <iostream>
# include <cstring>
using namespace std;

int main(){

    int n,i,j,k,m;
    int money[9];//金钱的面值 
    int c1[10000],c2[10000];

    while(cin>>money[1]>>money[2]>>money[5]&&money[1]||money[2]||money[5]){
        //利用下标 
        memset(c1,0,sizeof(c1));
        memset(c2,0,sizeof(c2));

        m = money[1]*1+money[2]*2+money[5]*5;//计算出面值的最大值 
        for(i=0;i<=money[1];i++){//初始化第一项 
            c1[i] = 1; 
        } 

        for(i=2;i<=5;i+=3){//代表第二项与第三项 
            for(j=0;j<=m;j++){// m代表最大的面值, 
                for(k=0;k+j<=m&&k/i<=money[i];k+=i){ //面值k=i*money[i];  k代表2或5面值的和 
                    c2[k+j]+= c1[j]; 
                }
            }

            for(k=0;k<=m;k++){
                c1[k] = c2[k];
                c2[k] = 0;
            }
        }

        for(i=1;i<=m;i++){
            if(!c1[i]){
                break;
            }
        }

        cout<<i<<endl;
    }


}

方法2:

# include <iostream>
using namespace std;

int main()
{
    int a,b,c;
    while(cin>>a>>b>>c)
    {
        if(a==0&&b==0&c==0)
        break;
        if(a==0)
        printf("1\n");
        else if(a+2*b<4)//a>=1,b只能是0 
        printf("%d\n",a+2*b+1);
        else//a!=0&&b1!=0 c不确定 
        printf("%d\n",a+2*b+5*c+1);
    }
    return 0;
}
代码3:
 # include <iostream>
 # include <cstring>
 using namespace std;

 # define MAX 10000 
 int c1[MAX],c2[MAX];
 int num[4];
 int main(){

    while(cin>>num[1]>>num[2]>>num[3]&&num[1]||num[2]||num[3]){

        int max_ = num[1]*1 + num[2]*2 + num[3]*5;
        int i,j,k;
        memset(c1,0,sizeof(c1));
        memset(c2,0,sizeof(c2));

        for(i=0;i<=num[1];i++){//对第一项初始化 
            c1[i] = 1;
        }

        //这两层for的作用就是第一项的每一个数与第二项的每一数相乘 
        for(i=0;i<=num[1];i++){//代表第一项 
            for(j=0;j<=num[2]*2;j+=2){//代表第二项 
                c2[i+j] += c1[i];// c2[i+j]-->代表取系数    c1[i]-->代表取ax^n中的a,即系数 
            }
        } 

            /*
             for循环中间的条件为什么是 j<=num[1]*1+num[2]*2
            上面是第一项与第二项的for循环是   x^a与x^b相加==x^(a+b)  最大值是num[1]*1+num[2]*2 
            */ 
            for(j=0;j<=num[1]*1+num[2]*2;j++){

                c1[j] = c2[j];
                c2[j] = 0;
            }   



        for(i=0;i<=num[1]*1+num[2]*2;i++){
            for(j=0;j<=num[3]*5;j+=5){
                c2[j+i] += c1[i];
            }
        } 
        for(j=0;j<=num[1]*1+num[2]*2+num[3]*5;j++){

                c1[j] = c2[j];
                c2[j] = 0;
        }   

        for(j=0;j<=max_;j++){
            if(c1[j]==0){
                break;
            }
        }

        cout<<j<<endl;


    }


    return 0;
 }
Runtime Error(ACCESS_VIOLATION)数组开的太小
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值