您的位置:首页 > 其它

Codeforces Round #272 (Div. 2) E. Dreamoon and Strings 动态规划

2017-03-14 21:43 351 查看
题目链接:这里

题意:给你一个串S,和另外一个串P。把k从0到|S|枚举,然后问你去掉k个字符后,s串里面最多有多少个不重叠的p字符串

解法:还以为是什么kmp之类的。看了题解才知道可以dp做。dp[i][j]表示考虑到第i个位置,去掉了j个字符的最大值。然后我们对于每一个位置,先暴力找到最少去掉多少个,才能加一,然后暴力去转移这个玩意儿就好了。

//CF 476E

#include <bits/stdc++.h>
using namespace std;
const int maxn = 2005;
const int limit = 2005;
char s1[maxn], s2[maxn];
int dp[maxn][maxn], len1, len2;//dp[i][j]代表考虑到i位置,去掉了j个字符的最大值
int match(int x){
if(x < len2) return limit;
int a = x, b = len2, tmp = 0;
while(a && b){
if(s1[a] == s2[b]) a--, b--;
else tmp++, a--;
}
if(b == 0) return tmp;
else return limit;
}
int main(){
scanf("%s%s", s1+1, s2+1);
len1 = strlen(s1+1);
len2 = strlen(s2+1);
memset(dp, 0, sizeof(dp));
for(int i = 0; i <= len1; i++)
for(int j = 0; j <= len1; j++)
if(i<j) dp[i][j] = -3000;
for(int i = 1; i <= len1; i++){
int x = match(i);
for(int k = 0; k <= len1; k++)
dp[i][k] = max(dp[i][k], dp[i-1][k]);
for(int k = 0; k <= len1; k++)
if(k>=x)
dp[i][k] = max(dp[i][k], dp[i-x-len2][k-x]+1);
}
for(int i = 0; i <= len1; i++) printf("%d ", dp[len1][i]);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: