题目: LINK
dp[i][j] 表示前i个字母里面去除j个字母后最多的不重复的p串的数量.
有两种情况,要么选取1~i中最后一个和p一样的串,要么不选取,dp[i][j] = max(dp[i-1][j], dp[ii][jj]+1), ii为匹配完p后在原串中的位置,jj为j-(匹配p过程中删去字母的数量);
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <string>
#include <vector>
#include <cmath>
#include <queue>
#include <map>
#include <set>
using namespace std;
#define INF 1000000000
//typedef __int64 LL;
#define N 2011
#define M 511
char str1[N], str2[N];
int dp[N][N];
int main()
{
#ifndef ONLINE_JUDGE
freopen("in.txt", "r", stdin);
#endif // ONLINE_JUDGE
scanf("%s%s", str1+1, str2+1);
int len1 = strlen(str1+1);
int len2 = strlen(str2+1);
for(int i = 1; i <= len1; i ++) {
int ii = i, jj = len2;
while(ii >= 1 && jj >= 1 ) {
if(str1[ii] == str2[jj]) jj--;
ii --;
}
if(jj == 0) {
int dif = i - ii - len2;
for(int th = 0; th <= ii; th ++) {
dp[i][dif + th] = dp[ii][th] + 1;
}
}
for(int th = 0; th < i; th ++) {
dp[i][th] = max(dp[i][th], dp[i-1][th]);
}
}
for(int i = 0; i <= len1; i ++) {
printf("%d ", dp[len1][i]);
}
return 0;
}