又做出一道题目了~

不得不说今天早上的收获真大,三道DP了~
下面是我写的题解:

题目:串的记数

问题编号:38

题目描述

一个长度为3N字符串满足:由NA,NB,NC组成,对于它的任意前缀,满足A的个数>=B的个数>=C的个数。求满足这样条件的字符串的个数。
数据范围:
10%
的数据满足0<=n<=5
100%
的数据满足0<=n<=60

输入格式

输入文件只有一行,为1个整数N(0<=n<=60)。

输出格式

所求的答案

样例输入

4

样例输出

462

 

这道题目很早以前就看到了。但是状态没设计好,一直没做出来,看了一下别人的状态,发现是三维的f[I,j,k]表示用iAjBkC组成的满足条件的穿的个数。而我一开始想的状态是一维的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] 要用高精度输出。。。。(讨厌压位~);


你可能感兴趣的:(曾经的OI)