1. 程式人生 > >刷題總結——regular words(hdu1502 dp+高精度加法+壓位)

刷題總結——regular words(hdu1502 dp+高精度加法+壓位)

name cab str output desc ets ces word ctype

題目:

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.

Input

There are mutiple cases in the input file.

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.

Sample Input

2 3

Sample Output

5 42

Source

Andrew Stankevich‘s Contest #10

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; }

刷題總結——regular words(hdu1502 dp+高精度加法+壓位)