母函数入门(杭电教程题目)

HDOJ 1398 ( Square Coins )

 

View Code
#include <cstdio>

#include <cstdlib>

#include <cstring>



const int MAXN = 301;

int c1[MAXN], c2[MAXN];



int main()

{

    int n;

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

    {

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

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



        for (int i = 2; i <= 17; ++i)

        {

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

                for (int k = 0; k + j <= n; k += i*i)

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

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

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

        }

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

    }

    return 0;

}

 

HDOJ 1028 ( Ignatius and the Princess III ) 

View Code
#include <cstdio>

#include <cstdlib>

#include <cstring>



const int MAXN = 125;

int c1[MAXN], c2[MAXN];



int main()

{

    int p;

    while (scanf("%d", &p) != EOF)

    {

        for (int i = 0; i <= p; ++i)

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



        for (int i = 2; i <= p; ++i)

        {

            for (int j = 0; j <= p; ++j)

                for (int k = 0; k + j <= p; k += i)

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



            for (int j = 0; j <= p; ++j)

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

        }

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

    }

    return 0;

}

 

HDOJ  1085 ( Holding Bin-Laden Captive! )  

View Code
#include <cstdio>

#include <cstdlib>

#include <cstring>



const int MAXN = 10010;

int c1[MAXN], c2[MAXN];



int main()

{

    int num1, num2, num5;

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

    {

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

            break;



        memset(c1, 0, sizeof(c1));

        memset(c2, 0, sizeof(c2));



        //int maxsum = num1 + 2 * num2 + 5 * num5;



        for (int i = 0; i <= num1; ++i)

            c1[i] = 1;



        int num[3], cnt[3];

        num[0] = 2; cnt[0] = num2;

        num[1] = 5; cnt[1] = num5;



        int sum = num1;

        for (int i = 0; i < 2; ++i)

        {

            for (int j = 0; j <= sum; ++j)

                for (int k = 0; k <= cnt[i]; ++k)

                    c2[j+k*num[i]] += c1[j];



            sum += num[i] * cnt[i];



            for (int j = 0; j <= sum; ++j)

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

        }

        int i;

        for (i = 1; i <= sum; ++i)

            if (!c1[i])

                break;

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

    }

    return 0;

}

 

HDOJ 1171 ( Big Event in HDU )

其实这题和上题1085一样的思路,用母函数解决。但是觉得这样没意思,于是用多重背包解决了下,顺便练练手

思路:

假设背包容量为总的价值的一半,那这个容量能拿到的价值则是输出的2个价值之一

View Code
#include <cstdio>

#include <cstdlib>

#include <cstring>



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

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



int v[51], m[51];

int dp[250005];



int main()

{

    int n;

    while (scanf("%d", &n) && n > 0)

    {

        int sum = 0, val = 0;

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

        {

            scanf("%d %d", &v[i], &m[i]);

            sum += m[i];

            val += v[i] * m[i];

        }

        memset(dp, 0, sizeof(dp));

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

        {

            int c = 1, j = m[i];

            while (c <= j)

            {

                j -= c;

                for (int k = val>>1; k >= c * v[i]; --k)

                    dp[k] = max(dp[k], dp[k-c*v[i]] + c*v[i]);

                c *= 2;

            }

            if (j > 0)

                for (int k = val>>1; k >= v[i] * j; --k)

                    dp[k] = max(dp[k], dp[k-j*v[i]] + j*v[i]);

        }

        printf("%d %d\n", max(dp[val>>1], val - dp[val>>1]), min(dp[val>>1], val - dp[val>>1]));

    }

    return 0;

}

 

 

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