acm pku 1221 Unimodal palindromic decompositions的逻辑推理过程

UNIMODAL PALINDROMIC DECOMPOSITIONS

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

Source

Greater New York 2002

 

分析: 最初拿到这个题目的时候,还是比较茫然的,有点无从下手的感觉,在网上查询了一下,发现该问题就是一个逻辑性的问题,可以做如下推理:

对任意一个正整数N,要想求得其Unimodal palindromic decompositions(UPD),可以先假设N的所有UPD已经分好,则其逻辑如下(itg[N][i]表示,对正整数N,其UPD分解中,最小的数为大于等于i的不同分解数目)

1)        对任意正整数i(i<N),若对正整数N的分解中存在i,则itg[N][i]可表示为N的分解中最小数等于i和最小数大于i,即大于等于i+1的部分,即:

itg[N][i] = itg[N-2i][i] + itg[N][i+1]

2)        初始化的问题,对于整数0的分解,根据1)中的讨论,有itg[0][i] = 1 (i=1,2, . . ., N);另外,当i>N/2时,itg[N][i] = 1,这是显然的;

3)        另外,根据作者遇到的情况,其结果可能超过长整型long,所以需要用到unsigned long型作为结果输出。

 

代码实现:

#include <string.h>

#include "iostream"

using namespace std;

 

#define N 512

unsigned long itg[N][N]; //最初使用long, 结果WA1

 

int main(void)

{

       long n ;

       int i, j;

 

       cin >> n;

       while(n != 0)

       {

              for(i = 0; i <= n; i++)

                     memset(itg[i], 0, sizeof(unsigned long)*N);

              for(i = 1; i <= n; i++)

              {

                     itg[0][i] = 1;

                     for(j = i/2+1; j <= i; j++)

                            itg[i][j] = 1;

              }

              for(i = 2; i <= n; i++ )

              {

                     for(j = i/2; j > 0; j--)

                            itg[i][j] = itg[i-2*j][j] + itg[i][j+1];

              }

              cout << n << " " << itg[n][1] << endl;

              cin >> n;

       }

       return 0;

}

 

提交结果:

Problem: 1221

 

User: uestcshe

Memory: 696K

 

Time: 16MS

Language: C++

 

Result: Accepted

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值