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

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;
}

 

-------------------------------------------------------

kedebug

Department of Computer Science and Engineering,

Shanghai Jiao Tong University

E-mail: kedebug0@gmail.com

GitHub: http://github.com/kedebug

-------------------------------------------------------

原文地址:https://www.cnblogs.com/kedebug/p/2758029.html