hdu 1284 dp

hdu 1284 dp

这题有很多种解法,可以用dp(包括从子问题推的和完全),母函数,分裂整数(这个还不了解),找规律等

下面给出其中一些方法的代码

 

找规律 
//hdu 1284 找规律
//给出n 看能n 内有多少个 2 和多少个3
//具体看代码和一下注视

#include <stdio.h>
#include <string.h>

#define N 35000

__int64 ans[N];

int main()
{
    int n;
//    计算i 可以由多少个 2 组成
    for(int i = 0; i < N; ++i)// 后面的 +1 表示全由1组成的(只有1中情况)
        ans[i] = i / 2 + 1; //则这一行表示由 2组成的情况加上由1组成的情况

//    从前面往后推,看能由几个3 组成,比如 ans[3]表示钱为3时
//    由1,2分硬币组成的情况,可以表示成钱为0 时加上一个3分硬币(这时方法数为
//     钱为 0 时由1,2,3组成的情况 加上钱为3时由1,2组成的方法数)
//    因此 ans[i] += ans[i-3]+1;不需要后面的+1
    for(int i = 3; i < N; ++i)
        ans[i] += ans[i-3];//这一行ans[i]就表示由2组成的情况加上由3组成的情况
//    ans[6]就相当于由2组成的情况ans[6] 加上 由1,2,3组成的情况的ans[6-3]
//    这样往后推,就可以把 由3分组成的情况加上去

    while(scanf("%d", &n) != EOF)
        printf("%I64d\n", ans[n]);
    return 0;
}

  

dp(完全背包)
dp(完全背包)


//dp(完全背包)
#include <stdio.h>
#include <string.h>

#define N 35000

int dp[N];

int main()
{
    dp[0] = 1;
    for(int i = 1; i <= 3; ++i)
    {   //背包容量为N,装入质量为i 的物品
        for(int j = i; j < N; ++j)
        {
            dp[j] += dp[j-i];
        }
    }
    int n;
    while(scanf("%d", &n) != EOF)
        printf("%d\n", dp[n]);
    return 0;
}

 

母函数
//hdu 1284 母函数

//              1分的             2分的             3分的
//母函数计算:(1+x+x^2+x^3+...)*(1+x^2+x^4+...)*(1+x^3+x^6+...)
//n 分钱要分解的方法则为 多项式相乘后 指数为n 的系数

#include <stdio.h>
#include <string.h>

#define N 35000

int ans[N], mul[N];

int main()
{
    for(int i = 0; i < N; ++i)
        ans[i] = 1;  //全用1分组成的方法都只有1种

    for(int i = 2; i <= 3; ++i)
    {
        for(int j = 0; j < N; ++j)
        {                                   //系数都为1
            for(int k = 0; j+k < N; k += i) //( 1 + x^k + x^(k+i) + x^(k+2i) + ... )
            {   //指数分别为j 和k 的多项式相乘 得到指数为 j+k项,所以第j项乘以第k项
                mul[j+k] += ans[j]; // 得到 j+k项 的系数为 j项的加上原本 j+k项的系数
            }
        }
        for(int j = 0; j < N; ++j)
        {
            ans[j] = mul[j];   //把系数保存到 ans数组里
            mul[j] = 0;        //初始化
        }
    }
    int n;
    while(scanf("%d", &n) != EOF)
    {
        printf("%d\n", ans[n]);
    }
    return 0;
}

 

posted @ 2012-04-18 00:34  gabo  阅读(334)  评论(0编辑  收藏  举报