标签:洛谷 P5694 int 括号 l2 l3 NOI2001 l1 dp
看完题面的第一反应是暴力
直接四维dp [i,j,k,l]表示深度为i,大中小括号分别为j,k,l时的方案
但发现s=ab这种情况不好处理,还要再枚举一个比d小的深度d'
时间复杂度变成了 D²*L的六次方
想开一个辅助数组g [i,j,k,l]表示深度小于i时的方案数,就可以直接拿出来用了
时间复杂度的问题解决了,但还不知道怎么处理重复计算
比如 [ ]()[ ]
在枚举[ ]时,()[ ]会被计算到
在枚举[ ]()时,[ ]会被计算到
难道是限制括号总长度来限制重复?胡思乱想完,无奈地看了题解
欸,真有趣!
解决重复计算是强制给a最外面匹配括号,就不会出现上述情况了,可以多画几个理解一下
(写到这里,强制转移,强制链接(处理环),最近遇到不止一次了,真是神奇的思想)
时间复杂度是,直接将我设想的辅助数组设为状态
直接四维dp [i,j,k,l]表示深度小于等于i,大中小括号分别为j,k,l时的方案
最后统计答案时用差分的思想dp[d][l1][l2][l3]-dp[d-1][l1][l2][l3]
(似乎做树形dp时有在洛谷遇到,也是计数,大意是给定节点,求二叉树深度为h时的方案数,那题也是直接设求不出来)
嗷,都是很巧妙的思想>_<
一些写代码过程中的细节:
1注意大中小括号有区别,不能乱,匹配小括号时要求大中括号为0
2算答案时可能出负数,要加一个mod
3不再是dp [0,0,0,0]=1了,是dp[i,0,0,0]=1,i属于(0,d)
这里是因为后面在枚举过程中,会出现和空串搭配的情况(也就是题面描述的第二种深度计算方式,我们的方程把三种方式都结合在一起了)
比如:
dp[i][j][k][l]=(dp[i][j][k][l]+(dp[i-1][x-1][y][z]*dp[i][j-x][k-y][l-z])%11380)%11380;
会出现x-1,y,z都为0的情况,如果只有dp[0,0,0,0]为1的话就wa了
get:边界的设置跟状态有关,要斟酌一下
4
if(j) { for(int x=1;x<=j;x++) for(int y=0;y<=k;y++) for(int z=0;z<=l;z++) { dp[i][j][k][l]=(dp[i][j][k][l]+(dp[i-1][x-1][y][z]*dp[i][j-x][k-y][l-z])%11380)%11380; } }
要保证j首先得不为0,才能强制加,第一次因为这个挂了。
code:
#include<bits/stdc++.h> using namespace std; int l1,l2,l3,d,dp[31][11][11][11]; int main() { freopen("lys.in","r",stdin); cin>>l1>>l2>>l3>>d; memset(dp,0,sizeof(dp)); for(int i=0;i<=d;i++) dp[i][0][0][0]=1; for(int i=1;i<=d;i++) for(int j=0;j<=l1;j++) for(int k=0;k<=l2;k++) for(int l=0;l<=l3;l++) { if(j) { for(int x=1;x<=j;x++) for(int y=0;y<=k;y++) for(int z=0;z<=l;z++) { dp[i][j][k][l]=(dp[i][j][k][l]+(dp[i-1][x-1][y][z]*dp[i][j-x][k-y][l-z])%11380)%11380; } } if(k) { for(int y=1;y<=k;y++) for(int z=0;z<=l;z++) { dp[i][j][k][l]=(dp[i][j][k][l]+(dp[i-1][0][y-1][z]*dp[i][j][k-y][l-z])%11380)%11380; } } if(l) { for(int z=1;z<=l;z++) { dp[i][j][k][l]=(dp[i][j][k][l]+(dp[i-1][0][0][z-1]*dp[i][j][k][l-z])%11380)%11380; } } } cout<<(dp[d][l1][l2][l3]-dp[d-1][l1][l2][l3]+11380)%11380; }
标签:洛谷,P5694,int,括号,l2,l3,NOI2001,l1,dp 来源: https://www.cnblogs.com/liyishui2003/p/16182157.html
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。