【模板题】动态规划:简单的整数划分问题,复杂的整数划分问题——01背包变形

4117:简单的整数划分问题——01背包变形

思路:dp[i][j]表示从1~j中选取数字能组成 i 的种类数
初始化:dp[1][i]=1;//1+...+1=i
      dp[i][1]=1;//仅选1=1
状态转移:1)i=j,则dp[i][j]=dp[i][j-1]+1;//仅选取j组成和=i,一种情况
         2)j>i,则第i+1,i+2,...,j 这些数没有用
         3)j                不使用j,dp[i][j-1]

AC代码:

#include
#include
using namespace std;
int dp[51][51];
int n,k;
int main()
{
	int i,j;
	while(cin>>n)
	{
		memset(dp,0,sizeof(dp));
		dp[0][0]=1;
		for (i=1;i<=n;i++)//和
			for (j=1;j<=n;j++)//枚举可选取的数
			{
				if (j==i)
					dp[i][j]=dp[i][j-1]+1;
				else if (i

7219:复杂的整数划分问题

初始化:dp[0][0]=1(这边有点不大明白,求大神解释!)

1、N划分成K个正整数之和的划分数目
    1)K个正整数中至少有一项为1,则去除1后求dp[i-1][j-1]
    2)K个正整数中没有1,则把每个数-1,求dp[i-j][j]

    注意j=1~i,边界条件!

2、N划分成若干个不同正整数之和的划分数目
    仅j

    其他同简单的整数划分

3、N划分成若干个奇正整数之和的划分数目
    1)j为偶数(j%2==0),dp3[i][j]=dp3[i][j-1]; 往后递推,不计算任何

    2)j为奇数,同简单的整数划分

AC代码:

#include
#include
using namespace std;
int dp1[51][51], dp2[51][51], dp3[51][51];
int n,k;
int main()
{
	int i,j;
	while(cin>>n>>k)
	{
		memset(dp1,0,sizeof(dp1));
		memset(dp2,0,sizeof(dp2));
		memset(dp3,0,sizeof(dp3));
		//Q1,将n划分为k个正整数
		dp1[0][0]=1;
		for (i=1;i<=n;i++)//和
			for (j=1;j<=i;j++)//划分为j个数,注意边界条件!!
				dp1[i][j]=dp1[i-j][j]+dp1[i-1][j-1]; //dp1[i-j][j]意思是把i-j划分为j个不同的数,然后每个数+1
		cout<i)
					dp2[i][j]=dp2[i][i];
				else
					dp2[i][j]=dp2[i-j][j-1]+dp2[i][j-1];//唯一的不同,dp2[i-j][j-1]
			}
		cout<

你可能感兴趣的:(dp)