Codeforces Round #272 (Div. 2) E. Dreamoon and Strings dp

时间:2023-03-08 15:09:03
Codeforces Round #272 (Div. 2) E. Dreamoon and Strings dp

题目链接:

http://www.codeforces.com/contest/476/problem/E

E. Dreamoon and Strings

time limit per test 1 secondmemory limit per test 256 megabytes
#### 问题描述
> Dreamoon has a string s and a pattern string p. He first removes exactly x characters from s obtaining string s' as a result. Then he calculates that is defined as the maximal number of non-overlapping substrings equal to p that can be found in s'. He wants to make this number as big as possible.
>
> More formally, let's define as maximum value of over all s' that can be obtained by removing exactly x characters from s. Dreamoon wants to know for all x from 0 to |s| where |s| denotes the length of string s.
#### 输入
> The first line of the input contains the string s (1 ≤ |s| ≤ 2 000).
>
> The second line of the input contains the string p (1 ≤ |p| ≤ 500).
>
> Both strings will only consist of lower case English letters.
#### 输出
> Print |s| + 1 space-separated integers in a single line representing the for all x from 0 to |s|.
#### 样例
> **sample input**
> aaaaa
> aa
>
> **sample output**
> 2 2 1 1 0 0

题意

给你一个文本串和一个模板串,求文本串删掉k(k=0,1,...,n)个字母后的最大不重叠子串个数。

题解

dp[i][j]表示前i个删掉j个字母后能得到的最大不重叠子串个数。

求出s1[i]结尾的往前能匹配到的位置,然后考虑这个匹配选和不选两种情况转移。

初始化的时候注意一点。

代码

#include<map>
#include<set>
#include<cmath>
#include<queue>
#include<stack>
#include<ctime>
#include<vector>
#include<cstdio>
#include<string>
#include<bitset>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<functional>
using namespace std;
#define X first
#define Y second
#define mkp make_pair
#define lson (o<<1)
#define rson ((o<<1)|1)
#define mid (l+(r-l)/2)
#define sz() size()
#define pb(v) push_back(v)
#define all(o) (o).begin(),(o).end()
#define clr(a,v) memset(a,v,sizeof(a))
#define bug(a) cout<<#a<<" = "<<a<<endl
#define rep(i,a,b) for(int i=a;i<(b);i++)
#define scf scanf
#define ptf printf typedef long long LL;
typedef vector<int> VI;
typedef pair<int, int> PII;
typedef vector<pair<int, int> > VPII; const int INF = 0x3f3f3f3f;
const LL INFL = 0x3f3f3f3f3f3f3f3fLL;
const double eps = 1e-8;
const double PI = acos(-1.0); //start---------------------------------------------------------------------- const int maxn = 2222; char s1[maxn],s2[maxn];
int dp[maxn][maxn];
int l1,l2; int match(int i){
int j=l2,ret=0;
while(i>0&&j>0){
if(s1[i]==s2[j]) j--;
else ret++;
i--;
}
if(j==0) return ret;
else return -1;
} void init(){
rep(i,0,maxn) rep(j,0,maxn) dp[i][j]=-INF;
rep(i,0,maxn){
for(int j=0;j<=i;j++){
dp[i][j]=0;
}
}
} int main() {
scanf("%s%s",s1+1,s2+1);
l1=strlen(s1+1),l2=strlen(s2+1);
init();
for(int i=1;i<=l1;i++){
int ret=match(i);
//不选
for(int k=0;k<=i;k++){
dp[i][k]=max(dp[i][k],dp[i-1][k]);
}
if(ret<0) continue;
int j=i-ret-l2;
//选
for(int k=0;k<=i;k++){
if(k>=ret) dp[i][k]=max(dp[i][k],dp[j][k-ret]+1);
}
}
for(int i=0;i<=l1;i++) if(dp[l1][i]<0) dp[l1][i]=0;
for(int i=0;i<l1;i++) printf("%d ",dp[l1][i]);
printf("%d\n",dp[l1][l1]);
return 0;
} //end-----------------------------------------------------------------------