BZOJ1566 [NOI2009]管道取珠 dp
2018-01-03 21:11
351 查看
有两个栈,每个栈从底向上有一些颜色为A或B的球,现将这些球全部取出,假设能得到k个不同的颜色序列,得到每个序列的方案数为ai.
求∑k
f470
i=1a2i.
这里需要巧妙转化
a2i可以看做两个人每人取一次,取得的序列相同的方案数。
那么设f[i][j][k]为第一个人在上面取i个,下面取j个,第二个人在上面取k个,下面取l=(i+j−k)个的方案数
滚动数组优化第一维,直接n3转移即可
并且卡了一波常数
可能还有更优秀的方法。。
求∑k
f470
i=1a2i.
这里需要巧妙转化
a2i可以看做两个人每人取一次,取得的序列相同的方案数。
那么设f[i][j][k]为第一个人在上面取i个,下面取j个,第二个人在上面取k个,下面取l=(i+j−k)个的方案数
滚动数组优化第一维,直接n3转移即可
并且卡了一波常数
可能还有更优秀的方法。。
#include<bits/stdc++.h> #define LL long long #define clr(x,i) memset(x,i,sizeof(x)) using namespace std; const int N=503,mo=1024523; char s1 ,s2 ; int n,m,f[3] ; inline void add(int &x,int y) { x+=y; if(x>mo)x-=mo; } int main() { scanf("%d%d%s%s",&n,&m,s1+1,s2+1); int now=0; f[now][0][0]=1; for(int i=0;i<=n;i++) { clr(f[now^1],0); for(int j=0;j<=m;j++) { int mk=min(i+j,n); for(int k=0;k<=mk;k++) { int l=i+j-k,v=f[now][j][k]; if(s1[i+1]==s1[k+1])add(f[now^1][j][k+1],v); if(s1[i+1]==s2[l+1])add(f[now^1][j][k],v); if(s2[j+1]==s1[k+1])add(f[now][j+1][k+1],v); if(s2[j+1]==s2[l+1])add(f[now][j+1][k],v); } } now^=1; } printf("%d",f[now][m] ); return 0; }
相关文章推荐
- 【bzoj1566】【NOI2009】【管道取珠】【dp】
- BZOJ 1566: [NOI2009]管道取珠 另类DP
- bzoj 1566: [NOI2009]管道取珠 (DP)
- BZOJ1566 [NOI2009]管道取珠 【dp】
- [BZOJ1566][NOI2009]管道取珠(DP)
- bzoj 1566: [NOI2009]管道取珠【dp】
- 【BZOJ 1566】 1566: [NOI2009]管道取珠 (DP)
- bzoj 1566 NOI 2009 管道取珠 DP 解题报告
- [BZOJ 1566][NOI2009]管道取珠(DP)
- [平方的拆分 DP] BZOJ 1566 [NOI2009]管道取珠
- bzoj 1566: [NOI2009]管道取珠 动态规划
- [BZOJ1566][NOI2009]管道取珠
- 【BZOJ 1566】: 【NOI2009】管道取珠 另类DP
- BZOJ1566 [NOI2009]管道取珠
- [bzoj1566][NOI2009]管道取珠
- [BZOJ]1566: [NOI2009]管道取珠
- BZOJ1566: [NOI2009]管道取珠
- [BZOJ 1056][NOI 2009]管道取珠(DP)
- bzoj1566 [NOI2009]管道取珠
- bzoj1566【Noi2009】管道取珠