ZOJ1353 Unimodal Palindromic Decompositions解題報告

今天刷題遇見的,覺得有必要記錄一下~~

原題如下:


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.


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


這道題說白了就是一道簡單的動態規劃問題,開始以爲是遞歸的題,結果用遞歸寫了一個,嚴重超時,連測試數據都過不了╯﹏╰

之後從網上搜了一下,幾乎沒什麼結題報告,(估計是因爲太簡單,大家都沒什麼問題<( ̄▽ ̄)> 沒辦法,暫時水平還比較凹~~)突然看到了教練在題目上寫的:“遞歸的思路,dp的代碼”,於是便用dp重寫,成功AC,代碼如下:

#include <iostream>
#include <cstring>
#include <cstdio>
#include <cstdlib>
using namespace std;
unsigned num[1000][1000];
void f()
{
    memset(num,0,sizeof(num));
    num[1][1]=1;
    num[2][1]=1;
    num[2][2]=1;
    for(int i=3;i<1000;i++)
    {
        if(i%2==0) num[i][i/2]=1;
        num[i][i]=1;
        int m=i/3;
        for(int j=1;j<=m;j++)
        {
            int t=i-2*j;
            for(int k=j;k<=t;k++)
                num[i][j]+=num[t][k];
        }

    }
}
int main()
{
    int n;
    f();
    while(cin>> n&&n!=0)
    {
        unsigned sum=0;
        for(int i=1;i<=n;i++)
        sum+=num[n][i];
        cout << n<<" "<<sum<<endl;
    }
    return 0;
}
思路就是分析一個數的最左邊的數,依次存儲在num數組中

num數組如下所示:

              1          2          3          4          5          6          7  …

1            1

2            1          1

3            1          0          1

4            2          1          0          1

5            2          0          0          0          1

6            4          1          1          0          0          1

7            3          1          0          0          0          0           1


例如對於7來說:

7=1+5+1

7=2+3+2

7=7

所以7的總數應當是5的總數中最左邊的數大於等於1的部分加上3的總數中最左邊數大於等於2的部分再加上1,依次遞歸循環

(注意:存儲數據時數據類型應當是unsigned,以免出現大數時不能正常表示)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章