当前位置: 代码迷 >> 综合 >> HDU1028 Ignatius and the Princess III(整数拆分:母函数||DP)
  详细解决方案

HDU1028 Ignatius and the Princess III(整数拆分:母函数||DP)

热度:33   发布时间:2024-01-16 13:32:40.0

题意:

给出一个值n,问有几种不同的拆分方法。

要点:

可以用母函数或DP来做,这里说一下母函数,基本思路是:写成(1+x^2+x^3+x^4……x^n)*(1+x^2+x^4+……)*(1+x^3+x^6+……)……这样,然后利用循环从每个括号开始算起,用c1存储前一次算出的所有指数对应的系数,c2暂存算上当前括号的对应系数,最后c1[n]就是答案。

母函数:

18281776 2016-09-18 09:36:22 Accepted 1028 0MS 1568K 693 B G++ seasonal
#include<iostream>
#include<algorithm>
using namespace std;int main()
{int n,i,j,k;while(scanf("%d",&n)!=EOF){int c1[125],c2[125];for(i=0;i<=n;i++)//一开始所有指数的系数都是1 {c1[i]=1;//c1表示未算当前括号内的前面元素的系数 c2[i]=0;//c2表示算上当前括号的总和,是个暂存的数组 }for(i=2;i<=n;i++)//从第2个括号开始算起,第一个都是1不用算 {for(j=0;j<=n;j++)//计算所有指数 {for(k=0;k+j<=n;k+=i)//第i个括号中每个元素与前面已经算出的元素相乘,指数变化 {c2[k+j]+=c1[j];}}for(j=0;j<=n;j++)//系数保存在前一个数组内 {c1[j]=c2[j];c2[j]=0;}}printf("%d\n",c1[n]);		}return 0;
}

DP:

基本思路是dp[i][j]表示i被拆分为最大因数为j的方法数,然后分为使用j和不用j两种。

18282153 2016-09-18 10:28:03 Accepted 1028 0MS 1636K 613 B G++ seasonal
#include<iostream>
#include<cstdlib>
#include<cstring> 
#include<algorithm>
using namespace std;
int dp[125][125];//dp[i][j]表示i被拆分为最大因数为j的方法数int cal(int n,int m)
{if(dp[n][m]!=-1)return dp[n][m];if(n<1||m<1) return dp[n][m]=0;if(n==1&&m==1)return dp[n][m]=1;if(n<m)return dp[n][m]=cal(n,n);if(n==m)return dp[n][m]=cal(n,m-1)+1;//自己整个作为一种 return dp[n][m]=cal(n,m-1)+cal(n-m,m);//有两种情况,使用m或不使用m 
} int main()
{int n;while(~scanf("%d",&n)){memset(dp,-1,sizeof(dp));printf("%d\n",cal(n,n));} return 0;
}




  相关解决方案