又做出一道题目了~

不得不说今天早上的收获真大,三道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]表示用iA,jBk个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<b)thenexit(f[0,0,0]);

       If(a<c)thenexit(f[0,0,0]);

       If(b<c)thenexit(f[0,0,0]);

       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] 要用高精度输出。。。。(讨厌压位~);


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值