题目链接:整数划分(三)
整数划分(三)
时间限制:
1000 ms | 内存限制:
65535 KB
难度:
5
-
描述
-
整数划分是一个经典的问题。请写一个程序,完成以下要求。
-
输入
-
多组输入数据。
每组输入是两个整数n和k。(1 <= n <= 50, 1 <= k <= n)
输出
-
对于输入的 n,k;
第一行: 将n划分成若干正整数之和的划分数。
第二行: 将n划分成k个正整数之和的划分数。
第三行: 将n划分成最大数不超过k的划分数。
第四行: 将n划分成若干个 奇正整数之和的划分数。
第五行: 将n划分成若干不同整数之和的划分数。
第六行: 打印一个空行
样例输入
-
5 2
样例输出
-
7 2 3 3 3
提示
-
样例输出提示:
1.将5划分成若干正整数之和的划分为: 5, 4+1, 3+2, 3+1+1, 2+2+1, 2+1+1+1, 1+1+1+1+1
2.将5划分成2个正整数之和的划分为: 3+2, 4+1
3.将5划分成最大数不超过2的划分为: 1+1+1+1+1, 1+1+1+2, 1+2+2
4.将5划分成若干 奇正整数之和的划分为: 5, 1+1+3, 1+1+1+1+1
5.将5划分成若干不同整数之和的划分为: 5, 1+4, 2+3
#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
long long dp[55][55];
int n, k;
long long ans1, ans2, ans3, ans4, ans5;
int main()
{
while ( scanf( "%d%d", &n, &k ) != EOF ) {
/* ans1 : 将n划分成若干正整数之和的划分数 */
/* ans3 : 将n划分成最大数不超过k的划分数 */
/* dp[i][j] : 将 i 划分成最大不超过 j 的种数
* dp[i][j] = dp[i-j][j] + dp[i][j-1] if i>=j;
* dp[i][j] = dp[i][i]; else;
*/
memset( dp, 0, sizeof(dp) );
dp[0][0] = 1;
for ( int i = 0 ; i <= n ; ++ i ) {
for ( int j = 1 ; j <= n ; ++ j ) {
if ( i >= j ) dp[i][j] = dp[i-j][j] + dp[i][j-1];
else dp[i][j] = dp[i][i];
}
}
ans1 = dp[n][n];
ans3 = dp[n][k];
/* ans2 : 将n划分成k个正整数之和的划分数 */
/* dp[i][j] : 将 i 划分成 j 个正整数的种数
* dp[i][j] = dp[i-j][j] + dp[i-1][j-1] if i>=j;
*/
memset( dp, 0, sizeof(dp) );
dp[0][0] = 1;
for ( int i = 0 ; i <= n ; ++ i ) {
for ( int j = 1 ; j <= k ; ++ j ) {
if ( i >= j ) dp[i][j] = dp[i-j][j] + dp[i-1][j-1];
}
}
ans2 = dp[n][k];
/* ans4 : 将n划分成若干个 奇正整数之和的划分数 */
/* dp[i][j] : 将 i 划分成 最大不超过 j 的种数
* dp[i][j] = dp[i-j][j] + dp[i][j-1]; if j % 2 == 1;
* dp[i][j] = dp[i][j-1]; else;
*/
memset( dp, 0, sizeof(dp) );
dp[0][0] = 1;
for ( int i = 0 ; i <= n ; ++ i ) {
for ( int j = 1 ; j <= n ; ++ j ) {
if ( j & 1 ) {
if ( i >= j ) dp[i][j] = dp[i-j][j] + dp[i][j-1];
else dp[i][j] = dp[i][i];
}
else dp[i][j] = dp[i][j-1];
}
}
ans4 = dp[n][n];
/* ans5 : 将n划分成若干不同整数之和的划分数 */
/* dp[i][j] : 将 i 划分成 j 个不同的数的种数
* dp[i][j] = dp[i-j][j-1] + dp[i][j-1]; if i>=j;
* dp[i][j] = dp[i][i]; else;
*/
memset( dp, 0, sizeof( dp ) );
dp[0][0] = 1;
for ( int i = 0 ; i <= n ; ++ i ) {
for ( int j = 1 ; j <= n ; ++ j ) {
if ( i >= j ) dp[i][j] = dp[i-j][j-1] + dp[i][j-1];
else dp[i][j] = dp[i][i];
}
}
ans5 = dp[n][n];
printf( "%lld\n%lld\n%lld\n%lld\n%lld\n\n", ans1, ans2, ans3, ans4, ans5 );
}
return 0;
}