• HDU 1028 Ignatius and the Princess III:dp or 母函数


    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1028

    题意:

      给你一个正整数n,将n拆分成若干个正整数之和,问你有多少种方案。

      注:"4 = 3 + 1"和"4 = 1 + 3"视为同一种方案。(加数是无序的)

    题解1(dp):

      表示状态:

        dp[n][m] = num of methods

        表示用均不超过m的元素组成n的方法数。

      

      如何转移:

        假设当前状态为dp[n][m].

        对于等于m的元素,有两种决策。要么不用,要么用。

          (1)不用:dp[n][m] += dp[n][m-1]

          (2)用: dp[n][m] += dp[n-m][m]

        综上:dp[n][m] = dp[n][m-1] + dp[n-m][m]

      

      找出答案:

        ans = dp[n][n]

      

      边界条件:

        dp[0][i] = 1  (0<=i<=MAX_N)

    题解2(母函数):

      要凑出n,每种方案无非是取几个1,几个2,几个3......

      这就是母函数的经典问题啦(取硬币)。

      

      构造母函数:

        G(x) = (1 + x^1 + x^2 + x^3...) * (1 + x^2 + x^4 + x^6...) * (1 + x^3 + x^6 + x^9...) * (1 + x^4 + x^8 + x^12...)...

      

      找出答案:

        x^n项的系数即为答案。

    AC Code(dp):

     1 // dp[n][m] = num of methods
     2 // n: the elems are up to n
     3 // m: each elem won't be not more than m
     4 // dp[n][m] = dp[n][m-1] + dp[n-m][m]
     5 // ans = dp[n][n]
     6 // dp[0][m] = 1
     7 
     8 #include <iostream>
     9 #include <stdio.h>
    10 #include <string.h>
    11 #define MAX_N 125
    12 
    13 using namespace std;
    14 
    15 int n;
    16 int dp[MAX_N][MAX_N];
    17 
    18 void cal_dp()
    19 {
    20     memset(dp,0,sizeof(dp));
    21     for(int i=0;i<MAX_N;i++)
    22     {
    23         dp[0][i]=1;
    24     }
    25     for(int i=1;i<MAX_N;i++)
    26     {
    27         for(int j=1;j<MAX_N;j++)
    28         {
    29             if(i>=j) dp[i][j]=dp[i][j-1]+dp[i-j][j];
    30             else dp[i][j]=dp[i][i];
    31         }
    32     }
    33 }
    34 
    35 int main()
    36 {
    37     cal_dp();
    38     while(cin>>n)
    39     {
    40         cout<<dp[n][n]<<endl;
    41     }
    42 }

    AC Code(Generating Function):

     1 #include <iostream>
     2 #include <stdio.h>
     3 #include <string.h>
     4 #define MAX_N 125
     5 
     6 using namespace std;
     7 
     8 int n;
     9 int ans[MAX_N];
    10 int temp[MAX_N];
    11 
    12 void generating_function(int n)
    13 {
    14     memset(ans,0,sizeof(ans));
    15     ans[0]=1;
    16     for(int i=1;i<=n;i++)
    17     {
    18         memset(temp,0,sizeof(temp));
    19         for(int j=0;j*i<=n;j++)
    20         {
    21             for(int k=0;k+j*i<=n;k++)
    22             {
    23                 temp[k+j*i]+=ans[k];
    24             }
    25         }
    26         memcpy(ans,temp,sizeof(temp));
    27     }
    28 }
    29 
    30 int main()
    31 {
    32     generating_function(120);
    33     while(cin>>n)
    34     {
    35         cout<<ans[n]<<endl;
    36     }
    37 }
  • 相关阅读:
    HDU 1195.Open the Lock
    HDU 2612.Find a way
    HDU 1240.Asteroids!
    HDU 1429.胜利大逃亡(续)
    HDU 1253.胜利大逃亡
    HDU 2102.A计划
    HDU 2579.Dating with girls(2)
    HDU 1782.逃离迷宫
    洛谷1297[国家集训队]单选错位
    spoj1026Favorite Dice
  • 原文地址:https://www.cnblogs.com/Leohh/p/7385142.html
Copyright © 2020-2023  润新知