区间dp
作者:互联网
练习一下区间dp,总结一下题型
括号配对问题 Brackets Sequence
链接:https://172.16.79.125/contest/view.action?cid=831#problem/A
题意:给一串括号序列。依照合法括号的定义,加入若干括号,使得序列合法。
一道典题,思路是括号配对加上路径回溯,找出输入的所有不配对单括号,在输出时将其补充成完整括号对即可
括号配对
求序列配对的括号量,使用三层循环,前两层枚举长度和起点,然后要注意括号配对时更新dp值。由于合法的括号对都是嵌套或者并列的,所以第三层的枚举中间点只能帮我们解决括号的并列,但是不能解决括号的嵌套,所以我们还要自己加入判断,即当该区间的左右端点括号匹配时,dp[l][r]=dp[l+1][r-1]+1。
路径回溯
这个也是典型,有两种方法,一种是不开辟数组,通过原来的dp转移方程来递归,另一种是开一个数组(一般dp过程可以简化数组维度,但路径回溯不可以,不过少部分题也可以),这个数组用来记录前驱(就是由谁更新了它),然后层层访问前驱即可。
以前写背包的路径回溯,两种方法都比较简单,现在看区间dp,感觉第二种好用点。区间dp由于第三层循环的存在,所以两种方法都会麻烦一点,第一种得遍历中间点,第二种得递归左区间和右区间。
代码:
#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>
using namespace std;
const int N = 1e2+10 , M = N<<1,mod=1e9+7;
typedef long long LL;
typedef pair<int,int> PII;
//#define x first
//#define y second
//int h[N],e[M],ne[M],idx;
//
//void add(int a,int b)
//{
// e[idx]=b,ne[idx]=h[a],h[a]=idx++;
//}
struct Node
{
int l1,r1;
int l2,r2;
};
char s[N];
int f[N][N];
Node path[N][N];
int st[N];
void dfs(int l,int r) //路径回溯
{
Node t =path[l][r];
if(t.l1==l+1&&t.r1==r-1)
{
st[l]=st[r]=1;
dfs(l+1,r-1);
}
else if((t.l1|t.l2|t.r1|t.r2)==0) return; //记得要加边界条件
else
{
dfs(t.l1,t.r1);
dfs(t.l2,t.r2);
}
}
int check(int l,int r) //检查括号是否匹配
{
if(s[l]=='('&&s[r]==')'||s[l]=='['&&s[r]==']') return 1;
return 0;
}
void deal(char c) //补全括号
{
if(c=='('||c==')') cout<<"()";
else if(c=='['||c==']') cout<<"[]";
}
void solve() //区间dp
{
cin>>s+1;
int size=strlen(s+1);
for(int len=2;len<=size;len++)
for(int r=len;r<=size;r++)
{
int l=r-len+1;
if(check(l,r)) //额外的判断条件
{
Node& t =path[l][r];
if(f[l][r]<f[l+1][r-1]+1) f[l][r]=f[l+1][r-1]+1,t.l1=l+1,t.r1=r-1;
}
for(int k=l;k<r;k++)
{
Node& t =path[l][r];
int sum=f[l][k]+f[k+1][r];
if(sum>f[l][r])
{
f[l][r]=sum;
t.l1=l,t.r1=k;
t.l2=k+1,t.r2=r;
}
}
}
dfs(1,size);
for(int i=1;i<=size;i++)
{
if(!st[i]) deal(s[i]);
else cout<<s[i];
}
cout<<'\n';
}
int main()
{
ios::sync_with_stdio(0);
cin.tie(0),cout.tie(0);
// int T;
// cin>>T;
// while(T--)
solve();
}
乡村邮局问题-Post Office(POJ-1160)
标签:r1,int,dfs,括号,l1,区间,dp 来源: https://www.cnblogs.com/Pleaf/p/16284346.html