[BZOJ 1056][NOI 2009]管道取珠(DP)
2015-03-04 20:41
218 查看
题目链接
http://www.lydsy.com/JudgeOnline/problem.php?id=1566思路
设上面的珠子序列是U,下面的是L,定义一个取珠子的操作序列的状态(i,j)表示上面的U取了i个,下面的L取了j个。那么∑a2i=\sum a_i^2=对于两个不同的操作序列X、YX、Y,它们最后取出的珠子序列是一样的,这样的有序对(X,Y)(X,Y)的个数。证明如下:假如最终取出的珠子序列为AA,它对应的操作序列个数为|Z||Z|,也就是说ai=|Z|2a_i=|Z|^2,那么根据分步计数原理,上面说的(X,Y)(X,Y)的对数显然等于|Z|2|Z|^2,也就是ai=|Z|2a_i=|Z|^2,得证。
那么这个(X,Y)(X,Y)的对数也很好求。用f[i1][j1][i2][j2]f[i_1][j_1][i_2][j_2]来表示操作序列XX的状态为(i1,j1)(i_1,j_1),操作序列YY的状态为(i2,j2)(i_2,j_2),并且当前X、YX、Y操作完以后取出来的珠子序列仍然是一样的(X,Y)(X,Y)方案数(就是按照上面说的来的)。DP方程也很好推,当前状态转移到下一状态后,两个操作序列各自增加的那个新柱子的颜色必须相同,DP方程如下。
![](https://www.byvoid.com/upload/wp/2010/01/clip_image0021.gif)
以上图片转自https://www.byvoid.com/blog/noi-2009-ball/
最后的那个j2j_2下标完全可以从前三个下标推出来,因此DP方程和DP过程都是三维的复杂度。
后记:
虽然这个题并不难,但是我WA了十多次,具体有很多细节需要注意:
1、输入了U、TU、T序列后,记得把它们翻转一下,因为我们定义的输入的珠子序列,出口处的柱子在下标1的位置。
2、注意最后一个下标j2j_2是从前三个下标推出来的,要判断j2j_2是否合法。
代码
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <algorithm> #define MAXN 505 #define MOD 1024523 using namespace std; int n,m; //注:状态(i,j)表示上面的U取了i个,下面的L取了j个 int f[MAXN][MAXN][MAXN]; //f[i1][j1][i2][j2]=X方法当前状态为(i1,j1),Y方法当前状态为(i2,j2),这样的有序对(X,Y)个数,j2=i1+j1-i2,因此j2状态可以略去 char U[MAXN],L[MAXN]; int add(int x,int y) { x+=y; if(x>MOD) x-=MOD; return x; //!!!! } int main() { scanf("%d%d",&n,&m); scanf("%s+1",U+1); //!!!! scanf("%s+1",L+1); //!!!! reverse(U+1,U+n+1); //!!!! reverse(L+1,L+m+1); //!!!! f[0][0][0]=1; for(int i=0;i<=n;i++) for(int j=0;j<=m;j++) for(int k=0;k<=n;k++) { int tmp=f[i][j][k],l=i+j-k; //X状态为(i,j),Y状态为(k,l) if(!tmp||l<0||l>m) continue; if(U[i+1]==U[k+1]) f[i+1][j][k+1]=add(f[i+1][j][k+1],tmp); if(U[i+1]==L[l+1]) f[i+1][j][k]=add(f[i+1][j][k],tmp); if(L[j+1]==U[k+1]) f[i][j+1][k+1]=add(f[i][j+1][k+1],tmp); if(L[j+1]==L[l+1]) f[i][j+1][k]=add(f[i][j+1][k],tmp); } printf("%d\n",f [m] ); return 0; }
相关文章推荐
- [BZOJ1566][NOI2009]管道取珠(DP)
- 【bzoj1566】【NOI2009】【管道取珠】【dp】
- BZOJ1566 [NOI2009]管道取珠 【dp】
- [平方的拆分 DP] BZOJ 1566 [NOI2009]管道取珠
- [BZOJ 1566][NOI2009]管道取珠(DP)
- 【BZOJ 1566】 1566: [NOI2009]管道取珠 (DP)
- BZOJ1566 [NOI2009]管道取珠 dp
- bzoj 1566: [NOI2009]管道取珠【dp】
- bzoj 1566: [NOI2009]管道取珠 (DP)
- bzoj 1566 NOI 2009 管道取珠 DP 解题报告
- BZOJ 1566: [NOI2009]管道取珠 另类DP
- BZOJ1566 【NOI2009】管道取珠
- 【BZOJ 1566】: 【NOI2009】管道取珠 另类DP
- BZOJ 1564: [NOI2009]二叉查找树( dp )
- [BZOJ]1566: [NOI2009]管道取珠
- bzoj1566: [NOI2009]管道取珠 dp
- 【BZOJ】1566: [NOI2009]管道取珠
- bzoj1566 [NOI2009]管道取珠
- 【DP】BZOJ1564- [NOI2009]二叉查找树(!!)
- [bzoj1566][NOI2009]管道取珠