CodeForces
来源:互联网 发布:带着淘宝去古代txt 编辑:程序博客网 时间:2024/06/05 03:48
题意:给你一个完整的括号匹配让你涂色,涂色的条件是
一个括号必须涂一边,而且只能涂一边。相邻的颜色不能相同而且只能涂蓝色和红色,然后求涂色方案数
题解:用思维然后dp[l][r][lc][rc]表示我此时涂的是第l到第r个括号边,lc表示之前左边涂的颜色,rc表示之前右边涂的颜色,0表示没涂,1表示涂蓝,2表示涂红色
然后判断l和r是在同一个括号,两个相邻的括号,两个括号不相邻的这些情况怎么转移一下即可
#include<iostream>#include<cstring>#include<cstdio>#include<stack>#include<algorithm>using namespace std;typedef long long int ll;const int mod = 1e9+7;const int mx = 705;ll dp[mx][mx][3][3];char s[mx];int p[mx];stack<int>st;ll dfs(int l,int r,int lc,int rc){ if(l>=r) return 1; if(dp[l][r][lc][rc]!=-1) return dp[l][r][lc][rc]; int x = p[l]; int y = p[r]; dp[l][r][lc][rc] = 0; if(x==r){ for(int i = 1; i <= 2; i++) if(i!=rc) dp[l][r][lc][rc] = (dp[l][r][lc][rc]+dfs(l+1,r-1,0,i))%mod; for(int i = 1; i <= 2; i++) if(i!=lc) dp[l][r][lc][rc] = (dp[l][r][lc][rc]+dfs(l+1,r-1,i,0))%mod; } else if(x+1==y){ for(int i = 1; i <= 2; i++) for(int j = 1; j <= 2; j++) if(i!=lc&&j!=rc) dp[l][r][lc][rc] = (dp[l][r][lc][rc]+dfs(l+1,x-1,i,0)*dfs(y+1,r-1,0,j))%mod; for(int i = 1; i<= 2; i++) for(int j = 1; j <= 2; j++) if(i!=j) dp[l][r][lc][rc] = (dp[l][r][lc][rc]+dfs(l+1,x-1,0,i)*dfs(y+1,r-1,j,0))%mod; for(int i = 1; i <= 2; i++) for(int j = 1; j <= 2; j++) if(i!=lc) dp[l][r][lc][rc] = (dp[l][r][lc][rc]+dfs(l+1,x-1,i,0)*dfs(y+1,r-1,j,0))%mod; for(int i = 1; i <= 2; i++) for(int j = 1; j <= 2; j++) if(j!=rc) dp[l][r][lc][rc] = (dp[l][r][lc][rc]+dfs(l+1,x-1,0,i)*dfs(y+1,r-1,0,j))%mod; } else{ for(int i = 1; i <= 2; i++) for(int j = 1; j <= 2; j++) if(i!=lc&&j!=rc) dp[l][r][lc][rc] = (dp[l][r][lc][rc]+dfs(l+1,x-1,i,0)*dfs(x+1,y-1,0,0)%mod*dfs(y+1,r-1,0,j))%mod; for(int i = 1; i<= 2; i++) for(int j = 1; j <= 2; j++) dp[l][r][lc][rc] = (dp[l][r][lc][rc]+dfs(l+1,x-1,0,i)*dfs(x+1,y-1,i,j)%mod*dfs(y+1,r-1,j,0))%mod; for(int i = 1; i <= 2; i++) for(int j = 1; j <= 2; j++) if(i!=lc) dp[l][r][lc][rc] = (dp[l][r][lc][rc]+dfs(l+1,x-1,i,0)*dfs(x+1,y-1,0,j)%mod*dfs(y+1,r-1,j,0))%mod; for(int i = 1; i <= 2; i++) for(int j = 1; j <= 2; j++) if(j!=rc) dp[l][r][lc][rc] = (dp[l][r][lc][rc]+dfs(l+1,x-1,0,i)*dfs(x+1,y-1,i,0)%mod*dfs(y+1,r-1,0,j))%mod; } // cout<<dp[l][r][lc][rc]<<endl;; return dp[l][r][lc][rc];}int main(){ memset(dp,-1,sizeof(dp)); int n; scanf("%s",s+1); n = strlen(s+1); for(int i = 1; i <= n; i++) if(s[i]=='(') st.push(i); else{ p[st.top()] = i; p[i] = st.top(); st.pop(); } ll ans = dfs(1,n,0,0); printf("%I64d\n",ans); return 0;}
阅读全文
0 0
- codeforces~~~
- Codeforces
- codeforces
- Codeforces
- codeforces
- codeforces
- Codeforces
- Codeforces
- CodeForces
- CodeForces
- CodeForces
- CodeForces
- CodeForces
- Codeforces
- Codeforces
- Codeforces
- Codeforces
- Codeforces
- 图像处理--图像的几何变换--旋转变换
- Vue2原理浅谈
- Web(二维字符数组的应用)(poj)
- java 反射机制 之 getMethods获取所有公有方法 和 getDeclaredMethods 获取本类所有方法
- C语言基础练习14
- CodeForces
- 图像旋转使用CImage实现
- VirtualDOM与diff(Vue实现)
- codeforces 840D 主席树
- FOC控制基于电阻的电流采样方案比较
- tf.split (API r1.3)
- vue-router源码分析-整体流程
- 求n个数的最小公倍数
- win10快捷键