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 second
memory 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-----------------------------------------------------------------------
posted @ 2016-08-31 10:48  fenicnn  阅读(117)  评论(0编辑  收藏  举报