题目:串的记数
问题编号:38
一个长度为3N字符串满足:由N个A,N个B,N个C组成,对于它的任意前缀,满足A的个数>=B的个数>=C的个数。求满足这样条件的字符串的个数。
数据范围:
10%的数据满足0<=n<=5
100%的数据满足0<=n<=60
输入文件只有一行,为1个整数N(0<=n<=60)。
所求的答案
4
462
这道题目很早以前就看到了。但是状态没设计好,一直没做出来,看了一下别人的状态,发现是三维的f[I,j,k]表示用i个A,j个B,k个C组成的满足条件的穿的个数。而我一开始想的状态是一维的f表示长度为i的字符串的个数。。。。。。这个不能转移,哎。然后这道题目也不是纯DP,还包含了高精度在里面。我写的是定义类型和运算符重载,但是没压位。一开始数组长度开成了60,爆掉了。然后改大点就过了。汗~
下面是高精度的代码:
Const maxn=60;maxm=1000;
Type node=array[0..maxm]of int;
Operator +(a,b:node)c:node;
Var i:int;
Begin
Fillchar(c,sizeof(c),0);
C[0]:=max(a[0],b[0]);
Fori:=1 to c[0] do
Begin
C:=c+a+b;
C[i+1]:=c[i+1]+c div 10;
C:=cmod 10;
End;
While(c[c[0]+1]>0)doinc(c[0]);
End;
然后就是DP了~,既然状态对了,那么转移就简单了。F[I,j,k]:=f[i-1,j,k]+f[I,j-1,k]+f[I,j,k-1];这个转移是一维的,灰常好写~这个DP~我还是写的记忆化搜索。(汗,这么喜欢记忆化搜索?)下面是代码:
Function search(a,b,c:node):node;
Begin
If(a
If(a
If(b
If(f[a,b,c][0]>0)thenexit(f[a,b,c]);
F[a,b,c]:=f[a,b,c]+search(a-1,b,c);
F[a,b,c]:=f[a,b,c]+search(a,b-1,c);
F[a,b,c]:=f[a,b,c]+search(a,b,c-1);
Exit(f[a,b,c]);
End;
然后初始条件就是:f[1,0,0][1]:=1;f[1,0,0][0]:=1;
主程序就是一句话:f[n,n,n,]:=search(n,n,n);
输出就是:f[n,n,n] 要用高精度输出。。。。(讨厌压位~);