POJ 1221 UNIMODAL PALINDROMIC DECOMPOSITIONS

总时间限制: 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

解题思路

刚刚入门动规,果然踩坑了,这道题写了一个小时,调了一个小时,不过也算是独立完成的第一道动规题(虽然写着写着就写成递归了orz),纪念一下。

子问题划分见代码,每次只进行一次分解,比如将8分解为(4,4)或者(1,6,1)、(2,4,2)。

奇数情况进入下一次迭代,偶数情况则终止迭代,比如8中的(4,4)不用再次迭代,(2,2,2,2)的情况在(2,4,2)中会被考虑到。总而言之,分解之后中间有数就迭代,中间没数了就完成使命了。

因为要满足单峰条件,所以进入子问题之后要告知上一位数字以进行比较。

需要注意的问题和技巧

TLE:太多冗余的计算了,开一个二维upd数组记录结果,避免重复迭代和循环。

WA:N<250,还是超了int的范围,要用unsigned int。

AC代码

#include<iostream>
#include<cstring>
using namespace std;

unsigned int upd[255][255];//保存结果,防止重复计算

int UPD(int s,int pre)//pre是当前位前一位的数字
{
    if (upd[s][pre]) return upd[s][pre];
    unsigned int cnt = 0;
    cnt++;//它自己也算是单峰
    for (int j = 1; j <= s / 2; j++)
    {
        if (s - 2 * j == 0 && j >= pre) cnt++;
        if ((s - 2 * j) >= j && j >= pre) cnt += UPD(s - 2 * j, j);
    }
    upd[s][pre] = cnt;
    return cnt;
}

int main()
{
    int sum;
    memset(upd, 0, sizeof(upd));
    while (cin >> sum)
    {
        if (sum == 0)break;
        unsigned int n_ = UPD(sum, 0);
        cout << sum << " " << n_ << endl;
    }
    return 0;
}
原文地址:https://www.cnblogs.com/yun-an/p/10963285.html