题目:
Problem Description
Consider words of length 3n over alphabet {A, B, C} . Denote the number of occurences of A in a word a as A(a) , analogously let the number of occurences of B be denoted as B(a), and the number of occurenced of C as C(a) .
Let us call the word w regular if the following conditions are satisfied:
A(w)=B(w)=C(w) ;
if c is a prefix of w , then A(c)>= B(c) >= C(c) .
For example, if n = 2 there are 5 regular words: AABBCC , AABCBC , ABABCC , ABACBC and ABCABC .
Regular words in some sense generalize regular brackets sequences (if we consider two-letter alphabet and put similar conditions on regular words, they represent regular brackets sequences).
Given n , find the number of regular words.
Let us call the word w regular if the following conditions are satisfied:
A(w)=B(w)=C(w) ;
if c is a prefix of w , then A(c)>= B(c) >= C(c) .
For example, if n = 2 there are 5 regular words: AABBCC , AABCBC , ABABCC , ABACBC and ABCABC .
Regular words in some sense generalize regular brackets sequences (if we consider two-letter alphabet and put similar conditions on regular words, they represent regular brackets sequences).
Given n , find the number of regular words.
Input
There are mutiple cases in the input file.
Each case contains n (0 <= n <= 60 ).
There is an empty line after each case.
Each case contains n (0 <= n <= 60 ).
There is an empty line after each case.
Output
Output the number of regular words of length 3n .
There should be am empty line after each case.
There should be am empty line after each case.
Sample Input
2
3
Sample Output
5
42
Source
Recommend
xhd
题解:
dp方程很好想:用f[a][b][c]表示A有a个B有b个C有c个的单词的总数量,则f[a][0][0]=1,f[a][b][0]=f[a-1][b][0]+f[a][b-1][0],f[a][b][c]=f[a-1][b][c]+f[a][b-1][c]+f[a][b][c-1],只是要注意f可能过大··所以要用高精度顺便压下位····
代码:
#include<iostream> #include<cstdio> #include<cstdlib> #include<cmath> #include<ctime> #include<cctype> #include<cstring> #include<string> #include<algorithm> using namespace std; const int N=61; const int Bit=10000; int f[N][N][N][30],n; inline void add(int f1[],int f2[]) { int l1,l2; for(l1=29;!f1[l1];l1--);for(l2=29;!f2[l2];l2--); if(l1<l2) l1=l2; for(int i=1;i<=l1;i++) f1[i]+=f2[i]; for(int i=1;i<=l1;i++) f1[i+1]+=f1[i]/Bit,f1[i]%=Bit; } inline void W(int f1[]) { int l1; for(l1=29;!f1[l1];l1--); cout<<f1[l1]; for(int i=l1-1;i>=1;i--) { if(f1[i]>=100&&f1[i]<1000) putchar('0'); else if(f1[i]>=10&&f1[i]<100) putchar('0'),putchar('0'); else if(f1[i]>=0&&f1[i]<10) putchar('0'),putchar('0'),putchar('0'); cout<<f1[i]; } cout<<endl;cout<<endl; } inline void getans() { for(int i=1;i<=60;i++) for(int j=0;j<=i;j++) for(int k=0;k<=j;k++) { if(j==0) f[i][j][k][1]=1; else if(k==0) { add(f[i][j][0],f[i][j-1][0]);add(f[i][j][0],f[i-1][j][0]); } else { add(f[i][j][k],f[i-1][j][k]);add(f[i][j][k],f[i][j-1][k]);add(f[i][j][k],f[i][j][k-1]); } } } int main() { //freopen("a.in","r",stdin); getans(); while(~scanf("%d",&n)) W(f[n][n][n]); return 0; }