类似于字典序比较的最长公共子序列,
只要找到状态方程就比较好搞,
从角标1开始计算不会出错,从0还是报错了;
切防止对比溢出要在本来的基础上+1计算;
言归正传:
DP类型都是状态方程很重要;
假设两个作对比,分别是s1,s2,则一定有 则dp[i][j] 就为s1前 i 个和s2前 j 个的公共子序列;
动态方程就是
if(s1[i]==s2[j])
{
dp[i][j]=dp[i-1][j-1]+1;
}
else
{
if(dp[i][j-1]>dp[i-1][j])
{
dp[i][j]=dp[i][j-1];
}
else dp[i][j]=dp[i-1][j];
}
AC代码就是:
#include <iostream>
#include <string.h>
#include <cstdio>
using namespace std ;
const int maxi = 1000;
int ma[maxi][maxi];
char s1[maxi],s2[maxi];
int main()
{
while(scanf("%s%s",s1+1,s2+1)!=EOF)
{
int n1 = strlen(s1+1);
int n2 = strlen(s2+1);
for(int i = 0 ; i <=n1;i++)
ma[i][0]=0;
for(int j = 0 ; j<=n2;j++)
ma[0][j]=0;
for(int i = 1 ; i<=n1;i++)
{
for(int j = 1 ; j<=n2;j++)
{
if(s1[i]==s2[j])
{
ma[i][j]=ma[i-1][j-1]+1;
}
else
{
if(ma[i][j-1]>ma[i-1][j])
{
ma[i][j]=ma[i][j-1];
}
else ma[i][j]=ma[i-1][j];
}
}
}
cout<<ma[n1][n2]<<endl;
}
return 0 ;
}
DP就是找状态方程去证明,慢慢找,需要大量练习;