母函数的初识——本拉登 hdu 1085

来源:互联网 发布:steam有mac游戏吗 编辑:程序博客网 时间:2024/04/29 06:28

题目链接 :母函数——本拉登

#include <iostream>#include <cstdio>#include <algorithm>using namespace std;int num[10] ;int c1[100000] , c2[100000] ;int main(){int i,j,k;while(cin >> num[1] >> num[2] >> num[5] && num[1] || num[2] || num[5]){int MAX = num[1] + num[2]*2 + num[5]*5;//   定义了一个max是为了减少运算量//  照常进行初始化for(i = 0;i <= MAX;i ++){c1[i] = 0;c2[i] = 0;}//  第一步 进行第一个数据的运算for(i = 0;i <= num[1];i ++)c1[i] = 1 ;        //  第二步 进行(1+x1+x2....)*(1+x2+x4...)的运算for(i = 0;i <= num[1];i ++){for(j = 0;j <= num[2]*2;j += 2)c2[j + i] += c1[i];}//  运算结束时,进行赋值和清空。for(i = 0;i <= num[1] + num[2]*2;i ++){c1[i] = c2[i];c2[i] = 0;}//  第三步 进行前面值的乘加for(i = 0;i <= num[1] + num[2]*2;i ++)for(j = 0;j <= num[5]*5;j += 5){c2[i + j] += c1[i];}        //  把临时变量的值给赋值,感觉并没有什么用处的for(i = 0;i <= MAX;i ++){c1[i] = c2[i];c2[i] = 0;}for(i = 0;i <= MAX;i ++)if( !c1[i] ){printf( "%d\n" , i ) ;break ;}if( i == MAX + 1 )printf( "%d\n" , i ) ;}return 0 ;}
母函数  用多重的情况
/**  Author:      illuz <iilluzen[at]gmail.com>*  File:        1085.cpp*  Create Date: 2014-05-25 11:34:37*  Descripton:  Generating Function*/#include <cstdio>#include <cstring>const int N = 1e4;int val[3] = {1, 2, 5}, cnt[3];int c1[N], c2[N], mmax;int main(){while (~scanf("%d%d%d", &cnt[0], &cnt[1], &cnt[2]) && (cnt[0] || cnt[1] || cnt[2])) {memset(c1, 0, sizeof(c1));memset(c2, 0, sizeof(c2));mmax = 0;for (int i = 0; i < 3; i++)mmax += cnt[i] * val[i];for (int i = 0; i <= cnt[0]; i++)// 处理第一种硬币c1[i] = 1;for (int i = 1; i < 3; i++) {// 对于1后面的每种硬币for (int j = 0; j <= mmax; j++) {if (c1[j] != 0) {// 对于之前的项(c1)for (int k = 0; k <= val[i] * cnt[i]; k += val[i]) {// 模拟与当前项式相乘if (j + k <= mmax)c2[j + k] += c1[j];}}}// 把当前项保存在c1,清空c2memcpy(c1, c2, sizeof(c1));memset(c2, 0, sizeof(c2));}int i;for (i = 0; i <= mmax; i++) {if (c1[i] == 0)break;}printf("%d\n", i);}return 0;}

一个充分利用数学原理的方法
#include <stdio.h>int main(){    int o,t,f,min;    while(1)    {        scanf("%d %d %d",&o,&t,&f);        if (!(o || t || f)) break;        if(!o) min=1;        else        {            if(o + 2*t < 4) min = (o + 2*t) + 1;            else min = o + 2*t + 5*f + 1;        }        printf("%d\n",min);    }    return 0;}
强大的暴力算法
#include <iostream>#include <cstring>using namespace std;int a[10000];int main()//暴力方法{    int n,m,l;    while(cin >> n >> m >> l){        if (n + m + l == 0) break;        memset(a,0,sizeof(a));        for (int i = 0;i <= n;i ++){            for (int j = 0;j <= m;j ++){                for (int k = 0;k <= l;k ++){                    a[i*1 + j*2 + k*5]=1;                }            }        }        for(int k = 1;k <= 8001;k ++){//这里不能用sum            if(!a[k]){                cout << k << endl; break;            }        }    }    return 0;}
古老的dp算法
#include<iostream>#include<cstring>using namespace std;int a[8005];int main()//DP{    int num[3],v[3] = {1,2,5};    while(cin >> num[0] >> num[1] >> num[2]){        if (num[0] == 0 && num[1] == 0 && num[2] == 0) break;        memset(a,0,sizeof(a));        int k,sum = 0;        for(int i = 0;i < 3;i ++){            sum += num[i]*v[i];//计算最大数值        }        //cout<<sum<<endl;        a[0] = 1;        for(int i = 0;i < 3;i ++){//DP算法            for(int k = sum;k >= v[i];k --){                for(int j = 1;j <= num[i];j ++){                    if(k-v[i]*j >= 0) a[k] = a[k-v[i]*j];//当前状态取决于前一状态                }            }        }        for(int k = 1;k <= sum+1;k ++){//这里不能用sum            if(!a[k]){                cout << k << endl; break;            }        }    }    return 0;}






原创粉丝点击