Shirlies
宁静专注认真的程序媛~

不是自己推出来的公式,看题解了才知道这个三维DP公式dp[i][j][k] = dp[i-1][j][k] + dp[i][j-1][k] + dp[i][j][k-1](i >= j >= k)

一看到这个题目,我的反应竟然是卡特兰数(一个有n个X和n个Y组成的字串,且所有的部分字串皆满足X的个数大于等于Y的个数。以下为长度为6的dyck words:XXXYYY   XYXXYY    XYXYXY    XXYYXY    XXYXYY),n<=60,即使不是卡特兰数,结果应该也会很大,所以要用到大数相加(真心的讨厌写大数相加相乘相除等的代码,磨蹭了些许时间,才写@_@,唉,什么时候自己写个有自己风格,至少自己以后也会认识它的模版,要用的时候直接拿来用就行了)。原来卡特兰数也可以用这种DP方式求的值啊~~~

代码如下:
 1 #include <iostream>
 2 #include <cstring>
 3 #include <algorithm>
 4 using namespace std;
 5 
 6 char words[62][62][62][100];
 7 
 8 void add(char a[],char b[])
 9 {
10     int lena = strlen(a);
11     int lenb = strlen(b);
12     int len = min(lena,lenb);
13     int carry = 0;
14     int i;
15     for(i = 0;i < len;i ++)
16     {
17         int num = a[i] - '0' + b[i] - '0' + carry;
18         a[i] = num % 10 + '0';
19         carry = num / 10;
20     }
21     while(i < lena)
22     {
23         int num = a[i] - '0' + carry;
24         a[i] = num % 10 + '0';
25         carry = num / 10;
26         i ++;
27     }
28 
29     while(i < lenb)
30     {
31         int num = b[i] - '0' + carry;
32         a[i] = num % 10 + '0';
33         carry = num / 10;
34         i ++;
35     }
36 
37     if(carry > 0)
38     {
39         a[i] = carry + '0';
40         a[i+1] = '\0';
41     }
42     else
43     {
44         a[i] = '\0';
45     }
46 }
47 
48 void dp()
49 {
50     memset(words,'\0',sizeof(words));
51     words[0][0][0][0] = '1';
52     words[0][0][0][1] = '\0';
53     for(int i = 1;i < 62;i ++)
54     {
55         for(int j = 0;j <= i;j ++)
56         {
57             for(int k = 0;k <= j;k ++)
58             {
59                 if(i - 1 >= j)
60                     add(words[i][j][k],words[i-1][j][k]);
61                 if(j-1 >= k)
62                     add(words[i][j][k],words[i][j-1][k]);
63                 if(k >= 1)
64                     add(words[i][j][k],words[i][j][k-1]);
65             }
66         }
67     }
68 }
69 int main()
70 {
71     int n;
72 
73     dp();
74     while(cin >> n)
75     {
76         if(n == 0)
77             cout << "0" << endl;
78         else
79         {
80             for(int i = strlen(words[n][n][n])- 1;i >= 0;i --)
81                 cout<<words[n][n][n][i];
82             cout << endl;
83         }
84         cout << endl;
85     }
86 
87     return 0;
88 }

 

posted on 2012-08-18 12:16  Shirlies  阅读(580)  评论(0编辑  收藏  举报