搜索——Ny 90 整数划分

1)   题目

整数划分

时间限制:3000 ms  |  内存限制:65535 KB

难度:3

描述

将正整数n表示成一系列正整数之和:n=n1+n2+…+nk 
其中n1≥n2≥…≥nk≥1k≥1 
正整数n的这种表示称为正整数n的划分。求正整数n的不 
同划分个数。 
例如正整数6有如下11种不同的划分: 
6
 
5+1
 
4+2
4+1+1 
3+3
3+2+13+1+1+1 
2+2+2
2+2+1+12+1+1+1+1 
1+1+1+1+1+1
 

输入

第一行是测试数据的数目M1<=M<=10)。以下每行均包含一个整数n1<=n<=10)。

输出

输出每组测试数据有多少种分法。

样例输入

1

6

样例输出

11


2)    题意

不再赘述。


3)    数据范围

测试数据数和n的值最大为10,数据量很小,手算都很容易。


4)    算法

搜索法

为了避免搜索到重复的划分方法,规定:

划分序列a1+a2+…+an,ai>=ai+1, 1<=i<n。

如下图是划分整数6的一棵搜索树。两方格内的数字是划分出的两个数。如6可以划分为5+1,4+2,3+3。


图中以红色数字为根节点一棵树,即为该红色数字的划分搜索树。


5)    代码

#include <iostream>
#include <cstdio>
#include <ctime>

using namespace std;

int count;

//num为要划分的数,minn为允许划分出的最小数
void Backtrack(int num, int minn)
{
	//printf("%d %d\n", num, minn);
	count++;
	if (num > 1)
	{
		int left, right;
		for (left = num-minn, right = minn; left >= right; left--, right++)
		{
			Backtrack(left, right);
		}
	}
}

int main(void)
{
	int ncases;
	scanf("%d", &ncases);
	while (ncases-- != 0)
	{
		int num;
		scanf("%d", &num);
		count = 0;
		//clock_t start, finish;
		//start = clock();
		Backtrack(num, 1);
		//finish = clock();
		//printf("%lf\n",  (double)(finish - start) / CLOCKS_PER_SEC);
		printf("%d\n", count);
	}
	return 0;
}

/*
#include<iostream>
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);
}
int main()
{
	int a;
	cin>>a;
	while(a--)
	{
		int n;
		cin>>n;
		cout<<q(n,n)<<endl;
	}
	return 0;
}
*/


6)    测试数据

10

1

2

3

4

5

6

7

8

9

7)    提交结果


第一次,没有按输入格式来,粗心。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

庞老板

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值