D - 柱爷的恋爱 区间dp、记忆化搜索
Source
My Solution
记忆化搜索
dp[a, b] 表示 [a, b) 内的方案数;
如果line[a] 要去掉, 则直接转移 dp[a, b] = dfs(a+1, b);
如果line[a]不去掉的, 那么如果line[a] 是'('就去找line[i] == ')',如果'['就找line[i] == ']', 找到一个算一个, 同时 [a+1, i) 和 [i+1, b)也要合法序列
然后dfs(a + 1, i) * dfs(i+1, b);
然后调用dfs(0,n) 就好了,找出[0,n) 内的方案数:
复杂度O(n^3);
#include <iostream>
#include <cstdio>
#include <string>
#include <cstring>
using namespace std;
typedef long long LL;
const int maxn = 300 + 8, HASH = 1000000007;
LL dp[maxn][maxn]; //主要是 有 (int)a*(int)b 的这个可能int溢出
string line;
/*
inline LL add(int a, int b)
{
LL c = a + b;
return c >= HASH ? c - HASH : c;
}
*/
LL dfs(int a, int b)
{
LL& res = dp[a][b];
if(res == -1){
if(a == b){
res = 1;
}
else{
res = 0;
//line[a] is not removed
char goalbra = '\0';
if(line[a] == '('){
goalbra = ')';
}
else if(line[a] == '['){
goalbra = ']';
}
if(goalbra != '\0'){
for(int i = a + 1; i < b; i++){
if(line[i] == goalbra){
res = (res + dfs(a + 1, i)*dfs(i + 1, b)) % HASH;
}
}
}
//line[a] is removed
res = (res + dfs(a + 1, b)) % HASH;
}
}
return res;
}
int main()
{
#ifdef LOCAL
freopen("a.txt", "r", stdin);
#endif // LOCAL
int n;
scanf("%d", &n);
cin>>line;
memset(dp, 255, sizeof dp);
//cout<<dp[0][0]<<endl;
printf("%lld", dfs(0, n) - 1);//不能全部去掉,所有有个 [a,a) 不能return 1 故这里 subtract 1 to find the wanted answer
return 0;
}
非特殊说明,本博所有文章均为博主原创,未经许可不得转载。
https://www.prolightsfxjh.com/
Thank you!
------from ProLightsfx
非特殊说明,本博所有文章均为博主原创,未经许可不得转载。
如经许可后转载,请注明出处:https://prolightsfxjh.com/article/2016-uestc-training-for-dynamic-programming-d/
共有 0 条评论