NYOJ 176 整数划分(二)

整数划分(二)

时间限制: 1000 ms  |  内存限制: 65535 KB
难度: 3
描述

把一个正整数m分成n个正整数的和,有多少种分法?

例:把5分成3个正正数的和,有两种分法:

1 1 3

1 2 2

输入
第一行是一个整数T表示共有T组测试数据(T<=50)
每组测试数据都是两个正整数m,n,其中(1<=n<=m<=100),分别表示要拆分的正数和拆分的正整数的个数。
输出
输出拆分的方法的数目。
样例输入
2
5 2
5 3
样例输出
2
2
来源

[张云聪]原创

这个题是对m划分为n个数,注意与90题的区别,但是思路差不多:

设dp[m][n],为题义要求

当n==m时,这个时候只有一种划分方法及n个一;

当n>m时,这个时候划分数为0,因为当划分的数全为1时为最多的划分个数(此时m=n),所以n不能大于m

当n<m时,这个时候可以这样看:

设所有划分出的数都大于1,即最小的划分数为2,这种情况可以看作先把n个数设为1,然后再从剩下的m-n个数中划分为n个数即dp[m-n][n]

若这n个划分数中肯定含有一个1,则相当于对m-1进行n-1个数的划分即dp[m-1][n-1]

所以dp[m][n]=dp[m-n][n]+dp[m-1][n-1];

#include<iostream>
#define MAX 105
using namespace std;
int dp[MAX][MAX];
int main(){
	int T; cin>>T;
	for(int i=1;i<MAX;i++){
		dp[i][1]=dp[1][i]=1;
	}
	for(int i=1;i<MAX;i++){
		for(int j=1;j<MAX;j++){
			if(i==j){
				dp[i][j]=1;
			}
			else if(i<j){
				dp[i][j]=0;
			}
			else if(i>j){
				dp[i][j]=dp[i-j][j]+dp[i-1][j-1];
			}
		}
	}
	while(T--){
		int m,n; 
		cin>>m>>n;
		cout<<dp[m][n]<<endl;
	}
}

  

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值