整数的拆分问题

// 整数的拆分.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <iostream>
#include <vector>
using namespace std;

int q(int n , int m)
{
	if(n < 1 || m < 1)
		return 0;
	if(n == 1 || m == 1)
		return 1;
	if(n < m)
		return q(n , n);
	if(n == m)
		return q(n , m - 1) + 1;
	return q(n , m - 1) + q(n - m , m);
}

void dfs(int sum , vector<int>& vec , int curnum , int id)
{
	int i;
	if(curnum == sum)
	{
		static int inum = 1 ;
		cout<<"方案 "<<inum++<<": ";
		for(i = 0; i < vec.size() ; ++i)
			cout<<vec[i]<<" ";
		cout<<endl;
		return;
	}

	for(i = id ; i <= sum; ++i)
	{
		if(curnum + i <= sum)
		{
			vec.push_back(i);
			dfs(sum , vec , curnum + i , i);
			vec.pop_back();
		}
		else
			break;
	}
}

int main(void)
{
	int n,i,j,dp[121][121];
	for(i = 1 ; i < 121 ; ++i)
	{
		for(j = 1 ; j < 121 ; ++j)
		{
			if(i == 1 ||  j == 1)
				dp[i][j] = 1;
			else if(i > j)
				dp[i][j] = dp[i][j-1] + dp[i-j][j];
			else if(i == j)
				dp[i][j] = dp[i][j-1] + 1;
			else
				dp[i][j] = dp[i][i];
		}
	}

	while(scanf("%d",&n)!=EOF)
	{
		cout<<dp[n][n]<<endl;
		cout<<q(n,n)<<endl;
		vector<int> vec;
		dfs(n , vec , 0 , 1);
		cout<<endl;
	}

	system("pause");
	return 0;
}
如,对于正整数n=6,可以拆分为:
6
5+1
4+2, 4+1+1
3+3, 3+2+1, 3+1+1+1
2+2+2, 2+2+1+1, 2+1+1+1+1
1+1+1+1+1+1+1
现在的问题是,对于给定的正整数n,程序输出该整数的拆分种类数(HDOJ  1028)。

DP思路:
n = n1 + n2 + n3 + n4 + .... + nk
状态表示:将n划分为k个数相加的组合方案数记为 q(n,k)。(相当于将n个苹果放入k个盘子)
状态转移:
(1)若k>n,则盘子数大于苹果数,至少有k-n个空盘子,可以将其拿掉,对组合方案数无影响。
q(n,k) = q(n,n)
(2)若k<=n,则盘子数小于等于苹果数,则分为两种情况
1.至少有一个盘子空着:q(n,k) = q(n,k-1)
2.所有盘子都不空:q(n,k) = q(n-k,k)

q(n,k) = q(n,k-1) + q(n-k,k)

没想明白为什么分为盘子 都不空 和 有一个空 两种情况???

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值