bzoj1566

好题,这道题体现了换一个角度计数的思想

a1^2+a2^2+……ak^2=(变成第1种输出序列的操作序列数目)^2+(变成第2种输出序列的操作序列数目)^2……

脑洞大一点,这就相当于两个操作序列变成相同输出序列的对数(包括自己和自己)

于是dp即可……dp[i,j,k]表示输出到第i个,第一个操作序列在上面取了j个,第二个操作序列在上面取了k个,怎么弄大家都会……

 1 const mo=1024523;
 2
 3 var s1,s2:array[0..600] of char;
 4     p,m,n,i,j,k,j1,k1:longint;
 5     f:array[0..1,0..510,0..510] of longint;
 6
 7 procedure reverse;
 8   var s:ansistring;
 9   begin
10     readln(s);
11     for i:=1 to n do
12       s1[n-i+1]:=s[i];
13     s1[n+1]:=‘$‘;
14     readln(s);
15     for i:=1 to m do
16       s2[m-i+1]:=s[i];
17     s2[m+1]:=‘#‘;
18   end;
19
20 begin
21   readln(n,m);
22   reverse;
23   f[0,0,0]:=1;
24   for i:=1 to m+n do
25   begin
26     p:=1-p;
27     fillchar(f[p],sizeof(f[p]),0);
28     for j:=0 to n do
29       for k:=0 to n do
30         if f[1-p,j,k]>=mo then f[1-p,j,k]:=f[1-p,j,k] mod mo;
31     for j:=0 to n do
32       for k:=0 to n do
33       begin
34         j1:=i-1-j;
35         k1:=i-1-k;
36         if (j1>=0) and (k1>=0) and (j1<=m) and (k1<=m) then
37         begin
38           if s1[j+1]=s1[k+1] then inc(f[p,j+1,k+1],f[1-p,j,k]);
39           if s1[j+1]=s2[k1+1] then inc(f[p,j+1,k],f[1-p,j,k]);
40           if s2[j1+1]=s1[k+1] then inc(f[p,j,k+1],f[1-p,j,k]);
41           if s2[j1+1]=s2[k1+1] then inc(f[p,j,k],f[1-p,j,k]);
42         end;
43       end;
44   end;
45   writeln(f[p,n,n] mod mo);
46 end.

时间: 2024-10-14 14:19:01

bzoj1566的相关文章

bzoj1566[noi2009]管道取珠

bzoj1566[noi2009]管道取珠 题意: 有个装置,左侧有上下两条管道分别有n个和m个不同颜色的两种球,右侧一条空管道.每次可以选左侧的一条管道将最右侧的球推到右侧管道,经过n+m次操作,右侧管道从右到左形成一个输出序列.求不同种类的输出序列的产生方式数的平方之和.n,m≤500 题解: 将题目转化成两个人同时取,取出来的序列相同的可能性有多少种.于是做dp.方程见代码.f[i][j][k][l]表示第一个人取了i个Aj个B第二个人取了k个Al个B. 代码: 1 #include <c

BZOJ1566 【NOI2009】管道取珠

题面 这是一道DP神题,直到我写下这句题解时也没有想明白-- 首先,这道题要我们求所有(不同输出序列的方案数)的平方和,于是我们当然就想到求所有不同输出序列的方案数--(大雾) .这道题一个巧妙的地方就在于对问题的转化.(以下摘自BYVoid大神的题解) 假设同时有两个人X & Y在玩这个游戏,设X从up取了i个珠子(不一定连续),从down取了j个珠子,取出来的珠子组成的序列为Q,操作序列为x,Y从up取了k个珠子,从down取了l个珠子,取出来的珠子组成的序列也为Q,操作序列为y,那么我们就

bzoj1566【Noi2009】管道取珠

题意:http://www.lydsy.com/JudgeOnline/problem.php?id=1566 两个栈不断pop,共C(n+m,n)种,ai表示每个相同序列的方案数,求∑(ai^2) sol  :首先,将相同的序列看做两个人选取后相同的方案数 考虑Dp,dp[i][j][k][l]表示第一个人从上面选i个,下面选j个,第二个人上k个下l个的答案 显然第四维状态可以由前三维决定 不过还是不太好转移,将状态换为dp[i][j][k]表示选了i个点,第一个人从上面选了j个,第二个人从上