POJ 1221

UNIMODAL PALINDROMIC DECOMPOSITIONS
Time Limit: 1000MS Memory Limit: 65536K
Total Submissions: 5903 Accepted: 2896
Description

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

Input consists of a sequence of positive integers, one per line ending with a 0 (zero) indicating the end.
Output

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.
Sample Input

2
3
4
5
6
7
8
10
23
24
131
213
92
0
Sample Output

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划分为回文整数序列。

题解:动态规划。
以6为例,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),
分解序列中最大为4时,有(1,4,1),此时对4继续进行分解依然可以构成回文数,即(1 1 2 1 1), (1 2 2 1), (1 1 1 1 1 1)
最大为3时得到(3,3),这种情况偶数才会有。最大为2时分解为(2 2 2)。
设状态方程为dp[i][j]表示对n进行划分时最小的整数>j的组合数。
考虑情况如下:
1)i/2 < j <= i,此时dp[i][j]只有分为i这一种情况,dp[i][j]=1
2)i<j,此时无法得到回文分解,dp[i][j]=0
3)i=0,此时代表将整数n分解为两个相同的数,且只有偶数才会有,dp[0][j]=1
4)定义转移方程:dp[i][j] = dp[i-2j][j] + dp[i][j+1]。第一种情况表示最小数=j时,若两侧同时加上j,情况数不变,继续对i-2j进行划分,第二种情况则是最小数>j的情况,是对划分情况的补充。
注意使用%lld打印
程序:
#include
#include
#include
#include
#include
#define MAXN 1010
using namespace std;

long long int dp[MAXN][MAXN];
int n;

int main(){
while(scanf("%d", &n) && (n != 0)){
memset(dp, 0, sizeof(dp));
for (int i = 1;i <= n;i++) {
dp[0][i] = 1;
}
for (int j = 1;j <= n;j++) {
for (int i = 1;i < j;i++) {
dp[i][j] = 0;
}
}
for (int i = 1;i <= n;i++) {
for (int j = i/2;j <= i;j++) {
dp[i][j] = 1;
}
}
dp[1][1] = 1;
for (int i = 1;i <= n;i++) {
for (int j = i/2;j >= 1;j–) {
dp[i][j] = dp[i - j*2][j] + dp[i][j+1];
}
}
printf("%d %lld\n", n, dp[n][1]);
}
return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值