https://ac.nowcoder.com/acm/problem/21303
题意中文的不说了;
做法,想到动态规划应该不难的,dp的表示
dp[i][j][k]表示A串扫描了前i个和B串扫描了前j个匹配的情况下,A串删除了的‘(’个数与‘)’的差值;
最终答案就是 dp[lena][lenb][0];
if (a[i] == b[j]) dp[i][j][k] |= dp[i - 1][j - 1][k];
if (a[i] == '(' && k > 0) dp[i][j][k] |= dp[i - 1][j][k - 1];
if (a[i] == ')') dp[i][j][k] |= dp[i - 1][j][k + 1];
转移方程如上,但是错了是怎么回事,加上一个!k就过了,简单说一下吧
首先看这组样列
(()(()))
()()
一看好像是可以的,但不过AC代码运行结果是不可以的,所以我猜测应该是每次只可以删除必须相连的“()”。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
char a[110],b[110];
int dp[110][110][110];
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin>>a+1;
cin>>b+1;
int la=strlen(a+1);
int lb=strlen(b+1);
dp[0][0][0]=1;
for(int i=1; i<=la; i++)
{
for(int j=1; j<=lb; j++)
{
for(int k=0; k<=la; k++)
{
if (!k && a[i] == b[j])
dp[i][j][k] |= dp[i - 1][j - 1][k];
if (a[i] == '(' && k > 0)
dp[i][j][k] |= dp[i - 1][j][k - 1];
if (a[i] == ')')
dp[i][j][k] |= dp[i - 1][j][k + 1];
//if(dp[i][j][k])
//cout<<i<<" "<<j<<" "<<k<<endl;
}
}
}
if(dp[la][lb][0]) cout<<"Possible"<<endl;
else cout<<"Impossible"<<endl;
return 0;
}
/**
(()(()))
()()
*/