编程题#1:UNIMODAL PALINDROMIC DECOMPOSITIONS
来源: POJ (http://bailian.openjudge.cn/practice/1221/)
注意: 总时间限制: 1000ms 内存限制: 65536kB
描述
A sequence of positive integers is Palindromic if it reads the same forward and backward. For example:
23 11 15 1 37 37 1 15 11 23
1 1 2 3 4 7 7 10 7 7 4 3 2 1 1
A Palindromic sequence is Unimodal Palindromic if the values do not decrease up to the middle value and then (since the sequence is palindromic) do not increase from the middle to the end For example, the first example sequence above is NOT Unimodal Palindromic while the second example is.
A Unimodal Palindromic sequence is a Unimodal Palindromic Decomposition of an integer N, if the sum of the integers in the sequence is N. For example, all of the Unimodal Palindromic Decompositions of the first few integers are given below:
1: (1)
2: (2), (1 1)
3: (3), (1 1 1)
4: (4), (1 2 1), (2 2), (1 1 1 1)
5: (5), (1 3 1), (1 1 1 1 1)
6: (6), (1 4 1), (2 2 2), (1 1 2 1 1), (3 3),(1 2 2 1), ( 1 1 1 1 1 1)
7: (7), (1 5 1), (2 3 2), (1 1 3 1 1), (1 1 1 1 1 1 1)
8: (8), (1 6 1), (2 4 2), (1 1 4 1 1), (1 2 2 2 1),(1 1 1 2 1 1 1), ( 4 4), (1 3 3 1), (2 2 2 2),(1 1 2 2 1 1), (1 1 1 1 1 1 1 1)
Write a program, which computes the number of Unimodal Palindromic Decompositions of an integer.
输入
Input consists of a sequence of positive integers, one per line ending with a 0 (zero) indicating the end.
输出
For each input value except the last, the output is a line containing the input value followed by a space, then the number of Unimodal Palindromic Decompositions of the input value. See the example on the next page.
样例输入
2
3
4
5
6
7
8
10
23
24
131
213
92
0
样例输出
2 2
3 2
4 4
5 3
6 7
7 5
8 11
10 17
23 104
24 199
131 5010688
213 1055852590
92 331143
提示
N < 250
解题思路参考:
http://blog.sina.com.cn/s/blog_7223fd910100x2bw.html
注:
求解最后的结果只需要枚举一下回文序列中间的数字就可以了(递推的终止条件!!!);偶数有两个,奇数只有一个。
用long long型数据
程序解答:
#include<iostream>
#include<cstring>
using namespace std;
//全局变量 R[251][251],动态规划的精髓!
long long R[251][251]; //记录数字N的以不小于m开头的单峰回文串数
int main(){
int N;
memset(R, 0, sizeof(R));
//cout << "当N最大取12时,以下依次输出 i " << "j " << "i-2*j " << "k " << ": " << "R[i][j]" << endl;
for (int i = 1; i <= 250; ++i){
//cout << endl;
R[i][i] = 1; //数字n以n开头则只有一种情况,如 6: (6);也是递推的终止条件!!!
if (i % 2 == 0)
R[i][i / 2] = 1; //偶数n以n/2开头则也只有一种情况,如 6: (3 3);也是递推的终止条件!!!
for (int j = 1; i - 2 * j >= j; ++j){ //此处k要从j处开始循环!
//此处i>=3时,j才能开始循环!
for (int k = j; i - 2 * j >= k; ++k){
R[i][j] += R[i - 2 * j][k];
//cout << "i:" << i << " " << "j:" << j << " " << "i-2*j:" << i - 2 * j << " " << "k:" << k << " :: " << R[i][j] << " ";
//cout << i << " " << j << " " << i - 2 * j << " " << k << " : " << R[i][j] << " ";
}
//cout << endl;
}
}
while (cin >> N){
if (N == 0)
break;
long long sum = 0; // sum也得是 long long 型!
for (int i = 1; i <= N; ++i)
sum += R[N][i];
cout << N << " " << sum << endl;
}
return 0;
}
其它解法参考:
http://blog.youkuaiyun.com/kindlucy/article/details/7434771
节省空间技巧(定义梯形数组 *R[N] 省空间):
long long *R[N];
for (int i = 0; i< N; i++){
R[i] = new long long[i + 1];
for (int j = 0; j <= i; j++){
R[i][j] = 0;
}
}
程序内部动态变化分析
当N最大取12时的内部变化举例:
比如R[8][1]=R[6][1]=R[4][1]=R[2][1]=1, R[2][1]是递推终止条件!!!
比如R[9][2]=R[5][4]=0, R[5][4]是递推终止条件!!!
比如R[9][2]=R[5][5]=1, R[5][5]是递推终止条件!!!
当N最大取12时,以下依次输出 i j i-2*j k : R[i][j]
3 1 1 1 : 1
4 1 2 1 : 1 4 1 2 2 : 2
5 1 3 1 : 1 5 1 3 2 : 1 5 1 3 3 : 2
6 1 4 1 : 2 6 1 4 2 : 3 6 1 4 3 : 3 6 1 4 4 : 4
6 2 2 2 : 1
7 1 5 1 : 2 7 1 5 2 : 2 7 1 5 3 : 2 7 1 5 4 : 2 7 1 5 5 : 3
7 2 3 2 : 0 7 2 3 3 : 1
8 1 6 1 : 4 8 1 6 2 : 5 8 1 6 3 : 6 8 1 6 4 : 6 8 1 6 5 : 6 8 1 6 6 : 7
8 2 4 2 : 1 8 2 4 3 : 1 8 2 4 4 : 2
9 1 7 1 : 3 9 1 7 2 : 4 9 1 7 3 : 4 9 1 7 4 : 4 9 1 7 5 : 4 9 1 7 6 : 4 9 1 7 7 : 5
9 2 5 2 : 0 9 2 5 3 : 0 9 2 5 4 : 0 9 2 5 5 : 1
9 3 3 3 : 1
10 1 8 1 : 7 10 1 8 2 : 9 10 1 8 3 : 9 10 1 8 4 : 10 10 1 8 5 : 10 10 1 8 6 : 10 10 1 8 7 : 10 10 1 8 8 : 11
10 2 6 2 : 1 10 2 6 3 : 2 10 2 6 4 : 2 10 2 6 5 : 2 10 2 6 6 : 3
10 3 4 3 : 0 10 3 4 4 : 1
11 1 9 1 : 5 11 1 9 2 : 6 11 1 9 3 : 7 11 1 9 4 : 7 11 1 9 5 : 7 11 1 9 6 : 7 11 1 9 7 : 7 11 1 9 8 : 7 11 1 9 9 : 8
11 2 7 2 : 1 11 2 7 3 : 1 11 2 7 4 : 1 11 2 7 5 : 1 11 2 7 6 : 1 11 2 7 7 : 2
11 3 5 3 : 0 11 3 5 4 : 0 11 3 5 5 : 1
12 1 10 1 : 11 12 1 10 2 : 14 12 1 10 3 : 15 12 1 10 4 : 15 12 1 10 5 : 16 12 1 10 6 : 16 12 1 10 7 : 16 12 1 10 8 : 16 12 1 10 9 : 16 12 1 10 10 : 17
12 2 8 2 : 2 12 2 8 3 : 2 12 2 8 4 : 3 12 2 8 5 : 3 12 2 8 6 : 3 12 2 8 7 : 3 12 2 8 8 : 4
12 3 6 3 : 1 12 3 6 4 : 1 12 3 6 5 : 1 12 3 6 6 : 2
12 4 4 4 : 1