zoukankan      html  css  js  c++  java
  • 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 }
  • 相关阅读:
    JDBC 实例--JDBC通过工具类DBUtil连接到数据库,让我们不再恐惧操作数据库
    揭开JDBC的神秘面纱,让JDBC数据库的连接参数不再神秘
    实验六 最小代价生成树
    实验五 背包问题和带时限的作业排序
    实验四 图的遍历算法设计与实现
    实验三 跳表算法设计与实现
    实验二 伸展树算法设计与实现
    算法实例一 算法问题求解基础--欧几里得递归算法和递归算法
    2013年 蓝桥杯预赛 java 本科A 题目
    java常用开发工具类之 图片水印,文字水印,缩放,补白工具类
  • 原文地址:https://www.cnblogs.com/Leohh/p/7385142.html
Copyright © 2011-2022 走看看