整数划分(n<400)
题目描述:
指把一个正整数n划分成多个大于等于1且小于等于其本身的整数,这些整数之和等于n,而且这些整数的顺序是无关的,即1+1+2与1+2+1是一种划分,请求出这些具体的划分。
输入:
一行,两个整数n和m,整数之间有一个空格,以“0 0”结束。n<400,m是指所有划分方案的第m顺序方案,具体方案是从大到小排序,方案排序也是先按第一个数(即划分中的最大数)的排,然后第二个数(即次最大的数)排,比如5+1排在4+2之前,紧接着是4+1+1,然后是3+3,等等。
输出:
每行对应一个答案,多个数,每个数之前有一个空格,从大到小排列,每行有回车。
样例输入:
4 4
5 6
7 15
7 14
5 1
0 0
样例输出:
2 1 1
2 1 1 1
1 1 1 1 1 1 1
2 1 1 1 1 1
5
#include<iostream>
#include<string.h>
#include<vector>
using namespace std;
vector <vector <long long>> result;
const int N = 403;
long long dp[N][N];
void Split(int n)
{
for (int i = 1; i <=n; i++)
{
for (int j = 1; j <= n; j++)
{
if (i == 1 || j == 1)
dp[i][j] = 1;
else if(i<j)
{
dp[i][j] = dp[i][i];
}
else if(i==j)
{
dp[i][j] = dp[i][j - 1] + 1;
}
else
{
dp[i][j] = dp[i][j - 1] + dp[i - j][j];
}
}
}
}
void Serach(long n, long long m)
{
vector<long long> temp;
long long index = n,column=n,count = m,remains=n,top = n;
while (true)
{
if ((dp[index][column] + count > dp[index][top]) && (dp[index][column - 1] + count <= dp[index][top]))
{
temp.push_back(column);
remains -= column;
count = count-(dp[index][top] - dp[index][column]);
index = remains;
top = column;
if (remains == 0)
break;
}
else
{
column--;
}
}
result.push_back(temp);
}
int main()
{
long long n, m;
while (cin>>n>>m)
{
if (n == 0 && m == 0)break;
memset(dp, 0, sizeof(dp));
Split(n);
Serach(n, m);
}
for (int i = 0; i < result.size(); i++)
{
for(int j=0;j<result[i].size();j++)
cout<<" "<<result[i][j];
cout << endl;
}
return 0;
}