母函数题目

hdu 1028 Ignatius and the Princess III 母函数模板题

http://acm.hdu.edu.cn/showproblem.php?pid=1028

题意:

整数的拆分。

母函数学习http://www.wutianqi.com/?p=596

View Code
#include <iostream>

#include <cstdio>

#include <cstring>

#include <algorithm>

#include <cmath>

#include <queue>

#include <stack>

#include <set>

#include <map>

#include <string>



#define CL(a,num) memset((a),(num),sizeof(a))

#define iabs(x)  ((x) > 0 ? (x) : -(x))

#define Min(a , b) ((a) < (b) ? (a) : (b))

#define Max(a , b) ((a) > (b) ? (a) : (b))



#define ll __int64

#define inf 0x7f7f7f7f

#define MOD 100000007

#define lc l,m,rt<<1

#define rc m + 1,r,rt<<1|1

#define pi acos(-1.0)

#define test puts("<------------------->")

#define maxn 100007

#define M 100007

#define N 127

using namespace std;

//freopen("din.txt","r",stdin);



int c1[N],c2[N];



void init(int n){

    int i,j,k;

    for (i = 0; i <= n; ++i){

        c1[i] = 1;//乘完后的系数

        c2[i] = 0;//乘的过程中的系数

    }



    for (i = 2; i <= n; ++i){

        //总共有n个括号,从第2个起每一个括号都要和前面那一个括号相乘

    //所以可以忽略第一个括号 

        for (j = 0; j <= n; ++j){//j代表最前面这个大括号的项数 

            for (k = 0; k + j <= n; k += i){//在大括号后面,x都是以i方递增的 

                c2[k + j] += c1[j];//这里就是大括号后面的括号与前面相乘的计算 

            }

        }

        for (j = 0; j <= n; ++j){

            c1[j] = c2[j];

            c2[j] = 0;

        }

    }

}

int main(){

    int n;

    init(120);

    while (~scanf("%d",&n)){

        printf("%d\n",c1[n]);

    }

    return 0;

}

 

hdu 1398 Square Coins

http://acm.hdu.edu.cn/showproblem.php?pid=1398

题意:

整数拆分的题目,只不过后边的括号里面的差值变成了i^2吧了。。

View Code
#include <iostream>

#include <cstdio>

#include <cstring>

#include <algorithm>

#include <cmath>

#include <queue>

#include <stack>

#include <set>

#include <map>

#include <string>



#define CL(a,num) memset((a),(num),sizeof(a))

#define iabs(x)  ((x) > 0 ? (x) : -(x))

#define Min(a , b) ((a) < (b) ? (a) : (b))

#define Max(a , b) ((a) > (b) ? (a) : (b))



#define ll __int64

#define inf 0x7f7f7f7f

#define MOD 100000007

#define lc l,m,rt<<1

#define rc m + 1,r,rt<<1|1

#define pi acos(-1.0)

#define test puts("<------------------->")

#define maxn 100007

#define M 100007

#define N 327

using namespace std;

//freopen("din.txt","r",stdin);



int c1[N],c2[N];

int pow2[320];



void init(int n){



    int i,j,k;

    for (i = 1; i <= 300; ++i){

        pow2[i] = i*i;

    }

    for (i = 0; i <= n; ++i){

        c1[i] = 1;

        c2[i] = 0;

    }



    for (i = 2; i <= n; ++i){

        for (j = 0; j <= n; ++j){

            for (k = 0; k + j <= n; k += pow2[i]){

                c2[k + j] += c1[j];

            }

        }

        for (j = 0; j <= n; ++j){

            c1[j] = c2[j];

            c2[j] = 0;

        }

    }

}

int main(){

    int n;

    init(300);

    while (~scanf("%d",&n)){

        if (!n) break;

        printf("%d\n",c1[n]);

    }

    return 0;

}

 

hdu 1085 Holding Bin-Laden Captive!

http://acm.hdu.edu.cn/showproblem.php?pid=1085

题意:

给出三种硬币,价值分别为1,2,5并给出他们的数量num1,num2,num5问他们不能够组合出来的的最小价值;

思路:

前边我们介绍的都是要么是每种数量为1个或者无限个,而这里给出了确定的数量。而且询问的是不能组合出来额最小值。所以有点绕,但思路还是没有改变。

我们只要在进行乘法运算时动态的增加括号里的项数即可。最后从小到大枚举一下就好。。

View Code
#include <iostream>

#include <cstdio>

#include <cstring>

#include <algorithm>

#include <cmath>

#include <queue>

#include <stack>

#include <set>

#include <map>

#include <string>



#define CL(a,num) memset((a),(num),sizeof(a))

#define iabs(x)  ((x) > 0 ? (x) : -(x))

#define Min(a , b) ((a) < (b) ? (a) : (b))

#define Max(a , b) ((a) > (b) ? (a) : (b))



#define ll __int64

#define inf 0x7f7f7f7f

#define MOD 100000007

#define lc l,m,rt<<1

#define rc m + 1,r,rt<<1|1

#define pi acos(-1.0)

#define test puts("<------------------->")

#define maxn 100007

#define M 100007

#define N 8007

using namespace std;

//freopen("din.txt","r",stdin);



int c1[N],c2[N];



int main(){

    int i,j,k;

    int num1,num2,num5;

    while (~scanf("%d%d%d",&num1,&num2,&num5)){

        if (!num1 && !num2 && !num5) break;

        int MAX = num1 + num2*2 + num5*5;//本身所能表示的最大数

        for (i = 0; i <= MAX; ++i){

            c1[i] = 0;

            c2[i] = 0;

        }

        for (i = 0; i <= num1; ++i) c1[i] = 1;//初始化第一个括号里的项

        //成第二个括号里的项

        for (j = 0; j <= num1; ++j){

            for (k = 0; k <= num2*2; k += 2){

                c2[k + j] += c1[j];

            }

        }

        for (j = 0; j <= num1 + num2*2; ++j){//动态的添加了

            c1[j] = c2[j];

            c2[j] = 0;

        }

        for (j = 0; j <= num1 + num2*2; ++j){

            for (k = 0; k <= num5*5; k += 5){

                c2[k + j] += c1[j];

            }

        }

        for (j = 0; j <= MAX; ++j){

            c1[j] = c2[j];

            c2[j] = 0;

        }

        for (i = 1; i <= MAX; ++i){

            if (!c1[i]) break;

        }

        printf("%d\n",i);

    }

    return 0;

}

 hdu Big Event in HDU

http://acm.hdu.edu.cn/showproblem.php?pid=1171

题意:

给出N中不同的设备,分别给出他们的价值以及数量,将这些设备分为两组,尽量使这两组的价值相等。输出各自的价值,若不相等大的在前边;

思路:

和上边一样。。。不多讲;

View Code
#include <iostream>

#include <cstdio>

#include <cstring>

#include <algorithm>

#include <cmath>

#include <queue>

#include <stack>

#include <set>

#include <map>

#include <string>



#define CL(a,num) memset((a),(num),sizeof(a))

#define iabs(x)  ((x) > 0 ? (x) : -(x))

#define Min(a , b) ((a) < (b) ? (a) : (b))

#define Max(a , b) ((a) > (b) ? (a) : (b))



#define ll __int64

#define inf 0x7f7f7f7f

#define MOD 100000007

#define lc l,m,rt<<1

#define rc m + 1,r,rt<<1|1

#define pi acos(-1.0)

#define test puts("<------------------->")

#define maxn 100007

#define M 100007

#define N 250007

using namespace std;

//freopen("din.txt","r",stdin);



int c1[N],c2[N];



int num[55],val[55];



int main(){

   // freopen("din.txt","r",stdin);

    int n,i,j,k;

    while (~scanf("%d",&n)){

        if (n < 0) break;

        int MAX = 0;

        for (i = 0; i < n; ++i){

            scanf("%d%d",&val[i],&num[i]);

            MAX += (val[i]*num[i]);

        }

        for (i = 0; i <= MAX; ++i){

            c1[i] = c2[i] = 0;

        }

        int len = val[0]*num[0];

        for (i = 0; i <= len; i += val[0]){

            c1[i] = 1;

        }

        for (i = 1; i < n; ++i){

            for (j = 0; j <= len; ++j){

                for (k = 0; k <= val[i]*num[i]; k += val[i]){

                    c2[k + j] += c1[j];

                }

            }

            len += val[i]*num[i];

            for (j = 0; j <= len; ++j){

                c1[j] = c2[j];

                c2[j] = 0;

            }

        }

        int ave = MAX/2;

        for (i = ave; i >= 0; --i){

            if (c1[i]) break;

        }

        int A = i;

        int B = MAX - A;

        printf("%d %d\n",max(A,B),min(A,B));

    }

    return 0;

}

你可能感兴趣的:(函数)