BestCoder Round #87 1002 Square Distance[DP 打印方案]

Square Distance

 
 Accepts: 73
 
 Submissions: 598
 Time Limit: 4000/2000 MS (Java/Others)
 
 Memory Limit: 65536/65536 K (Java/Others)
问题描述
一个字符串被称为square当且仅当它可以由两个相同的串连接而成. 例如, "abab", "aa"是square, 而"aaa", "abba"不是.

两个长度相同字符串之间的hamming distance是对应位置上字符不同的位数.

Alex有个偶数长度的字符串ss1s2...sns=s1​​s2​​...sn​​. 他想要找到一个字典序最小的square tt1t2...tnt=t1​​t2​​...tn​​ 使得ss和tt之间的hamming distance恰好是mm. 另外, ss和tt仅包含小写英文字母.
输入描述
输入包含多组数据, 第一行包含一个整数TT 1T500(1T500)表示测试数据组数. 对于每组数据:

第一行包含两个整数nn和mm 1n10000mnn(1n1000,0mn,n is even)表示字符串的长度和hamming distance. 第二行包含一个字符串ss.
输出描述
对于每组数据, 如果不存在这样的一个square, 输出"Impossible" (不包含引号). 否则, 输出字典序最小的square.
输入样例
3
4 1
abcd
4 2
abcd
4 2
abab
输出样例
Impossible
abab
aaaa


因为要字典序最小打印,所以倒着保存状态
f[i][j]表示i到n/2且hamming distance为j是否可行
DP一遍之后贪心从头开始选择就行了
//
//  main.cpp
//  bc87-1002
//
//  Created by Candy on 10/1/16.
//  Copyright © 2016 Candy. All rights reserved.
//

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <vector>
#include <string>
using namespace std;
const int N=1005,V=1e6+5;
inline int read(){
    char c=getchar();int x=0,f=1;
    while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
    while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
    return x;
}
int T,n,m,l,d[N][N];//dao xu
char s[N],t[N];
void dp(){
    memset(d,0,sizeof(d));
    d[l+1][0]=1;
    for(int i=l;i>=1;i--)
        for(int j=0;j<=m;j++){
            if(s[i]==s[i+l]) {
                d[i][j]|=d[i+1][j];
                if(j>=2) d[i][j]|=d[i+1][j-2];
            }else{
                if(j>=1) d[i][j]|=d[i+1][j-1];
                if(j>=2) d[i][j]|=d[i+1][j-2];
            }
            //printf("d %d %d %d
",i,j,d[i][j]);
        }
    if(!d[1][m]){printf("Impossible
");return;}
    int res=m;
    for(int i=1;i<=l;i++)
        for(int k=0;k<26;k++){
            int tmp=(s[i]-'a'!=k)+(s[i+l]-'a'!=k);
            if(d[i+1][res-tmp]){
                t[i]=t[i+l]=k+'a';
                res-=tmp;
                break;
            }
        }
    for(int i=1;i<=n;i++) putchar(t[i]);
    putchar('
');
}
int main(int argc, const char * argv[]) {
    T=read();
    while(T--){
        n=read();m=read(); l=n/2;
        scanf("%s",s+1);
        dp();
    }
    return 0;
}
原文地址:https://www.cnblogs.com/candy99/p/5925801.html