URAL 1635 Mnemonics and Palindromes

URAL 1635

思路:区间dp+贪心,先n^2处理出每段区间是否是回文串,然后贪心地找每一段1到i的最少分割。

代码:

#include<bits/stdc++.h>
using namespace std;
#define ll long long 
#define pb push_back
#define mem(a,b) memset(a,b,sizeof(a))

const int N=4e3+5;
string s;
int n;
int dp[N][N];
int ans[N];
int pre[N];
void init(){
    for(int len=1;len<=n;len++){
        for(int i=0;i+len-1<n;i++){
            int j=i+len-1;
            dp[i][j]=s[i]==s[j]&&(i+1>=j-1||dp[i+1][j-1]);
        }
    }
}
void dfs(int t){
    if(pre[t]==-1){
        for(int i=0;i<=t;i++)cout<<s[i];
        if(t!=n-1)cout<<' ';
        else cout<<endl;
        return ;
    }
    else{
        dfs(pre[t]);
        for(int i=pre[t]+1;i<=t;i++)cout<<s[i];
        if(t!=n-1)cout<<' ';
        else cout<<endl;
        return ;
    }
}
int main(){
    ios::sync_with_stdio(false);
    cin.tie(0);
    cin>>s;
    n=s.size();
    init();
    for(int i=0;i<n;i++){
        ans[i]=(i-1<0?0:ans[i-1])+1;
        pre[i]=i-1;
        for(int j=0;j<i;j++){
            if(dp[j][i]&&(j-1<0?0:ans[j-1])+1<ans[i]){
                ans[i]=(j-1<0?0:ans[j-1])+1;
                pre[i]=j-1;
            }
        }
    }
    cout<<ans[n-1]<<endl;
    dfs(n-1);
    return 0;
} 
原文地址:https://www.cnblogs.com/widsom/p/8361061.html