标签:
Description
Input
Output
Sample Input
die einkommen der landwirte sind fuer die abgeordneten ein buch mit sieben siegeln um dem abzuhelfen muessen dringend alle subventionsgesetze verbessert werden # die steuern auf vermoegen und einkommen sollten nach meinung der abgeordneten nachdruecklich erhoben werden dazu muessen die kontrollbefugnisse der finanzbehoerden dringend verbessert werden #
Sample Output
die einkommen der abgeordneten muessen dringend verbessert werden
这道题是LCS的变种,只需把数组类型改成string就可以了,重点在于对LCS模版的理解
LCS:求解最长公共子序列,由于动态规划无非是递归的一种优化,不如先来看看递归的解法
LCS(i,j)表示数组以数组1的i个为止和以数组2的第j个为止的最长公共子序列,注意是第i个字符为子串的末尾字符(这样才能达到无后效性的目的)
1.LCS(i-1,j-1)+1 (a【i】=b【j】)
LCS(i,j)={
2.max{LCS(i-1,j),LCS(i,j-1)} (a【i】!=b【j】)
对比递归,就能写出状态转移方程,可以用二维数组dp【i】【j】来表示状态LCS(i,j)
不过这个动态规划方程属于从已知推未知型,要特别注意给初始值
1.dp【i-1】【j-1】+1 (a【i】=b【j】) //如果相等,公共串的长度又加一了
dp【i】【j】={ 2.dp【0】【i】=0,dp【i】【0】=0 //初始值,如果某个数组的长度为0,那没必要说公共串了
3.max{dp【i-1】【j】,dp【i】【j-1】} (a【i】!=b【j】) //如果不相等,只能选择前一个值最大的状态
然后再因题制宜,在dp寻求最长公共子串时记录一下选了哪些字符,最后输出就好
#include"iostream"
#include"cstring"
using namespace std;
string a[110];
string b[110];
string c[110];
int dp[110][110];
int d[110][110];
int main()
{
int l1,l2;
while(cin>>a[1])
{
l1=2;
while(a[l1-1]!="#")
cin>>a[l1++];
l1-=2;
cin>>b[1];
l2=2;
while(b[l2-1]!="#")
cin>>b[l2++];
memset(dp,0,sizeof(dp));
memset(d,0,sizeof(d));
for(int i=1;i<=l1;i++)
for(int j=1;j<=l2;j++)
{
if(a[i]==b[j])
{
dp[i][j]=dp[i-1][j-1]+1;
d[i][j]=3;
}
else
{
if(dp[i-1][j]>dp[i][j-1])
{
dp[i][j]=dp[i-1][j];
d[i][j]=2;
}
else
{
dp[i][j]=dp[i][j-1];
d[i][j]=1;
}
}
}
int n=dp[l1][l2];
int i=l1;
int j=l2;
while(n)
{
while(d[i][j]!=3)
{
if(d[i][j]==2)
i--;
else j--;
}
n--;
c[n]=a[i];
i--;j--;
}
cout<<c[0];
for(int k=1;k<dp[l1][l2];k++) cout<<" "<<c[k];
cout<<endl