bnu 33966 Almost Palindrome 区间dp

来源:互联网 发布:ones刻录软件 编辑:程序博客网 时间:2024/06/05 17:51
区间dp【i】【j】记录区间【i,j】成回文串时不同对数
#include<algorithm>#include<iostream>#include<cstdio>#include<cstring>#include<string>#include<vector>#define REP(i, n) for(int i=0; i<n; i++)#define FF(i, a, b) for(int i=a; i<b; i++)#define FD(i, a, b) for(int i=a; i>=b; i--)#define CLR(a, b) memset(a, b, sizeof(a))#define PB push_backusing namespace std;char h[1100];int idx[1100];int dp[1010][1010];bool vis[1010][1010];int N;int n, k;int dpf(int l, int r){    if (l >= r) return 0;    if (vis[l][r]) return dp[l][r];    vis[l][r] = 1;    int &ans = dp[l][r];    ans = dpf(l + 1, r - 1);    if (h[l] != h[r])    ans += 2;    return ans;}void input(){    n = 0;    N = 0;    char c = getchar();    while (c != '\n')    {        N++;        if (c <= 'z' && c >= 'a')            h[n++] = c, idx[n - 1] = N;        else if (c <= 'Z' && c >= 'A')            h[n++] = c - 'A' + 'a', idx[n - 1] = N;        c = getchar();    }    h[n] = 0;}int main(){    int nc = 1;    while (~scanf("%d", &k))    {        k *= 2;        getchar();        input();        CLR(vis, 0);        int ans, ansi;        ans = -1;        for (int L = n; L >= 1; L--)        {            for (int i = 0; i + L - 1 < n; i++)            {                int j = i + L - 1;                if (dpf(i, j) <= k)                {                    if (ans < idx[j] - idx[i] + 1)                    {                        ans = idx[j] - idx[i] + 1;                        ansi = idx[i];                    }                    else if (ans == idx[j] - idx[i] + 1)                        ansi = min(ansi, idx[i]);                }            }        }        printf("Case %d: %d %d\n", nc++, ans, ansi);    }}