HDU 5903 Square Distance

$dp$预处理,贪心。

因为$t$串前半部分和后半部分是一样的,所以只要构造前一半就可以了。

因为要求字典序最小,所以肯定是从第一位开始贪心选择,$a,b,c,d,...z$,一个一个尝试过去,如果发现某字符可行,那么该位就选择该字符。

第$i$位选择字符$X$可行的条件:

记这一位选择字符$X$的情况下,对$dis$的贡献为$Q$,$1$至$i-1$位对$dis$贡献和为$F$;

如果第$i+1$位至第$\frac{n}{2}$位,对$dis$的贡献可以凑出$m-Q-F$,那么该位选择$X$可行。

所以可以记$dp[i][j]$表示,第$i$位至第$\frac{n}{2}$位,$dis$为$j$是否可以被凑出,倒着$dp$一下就可以了。

#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<vector>
#include<map>
#include<set>
#include<queue>
#include<stack>
#include<bitset>
#include<iostream>
using namespace std;
typedef long long LL;
const double pi=acos(-1.0),eps=1e-6;
void File()
{
    freopen("D:\\in.txt","r",stdin);
    freopen("D:\\out.txt","w",stdout);
}
template <class T>
inline void read(T &x)
{
    char c=getchar(); x=0;
    while(!isdigit(c)) c=getchar();
    while(isdigit(c)) {x=x*10+c-‘0‘; c=getchar();}
}

const int maxn=1010;
char s[maxn],ans[maxn];
int T,n,m;
int a[maxn],b[maxn];
bool dp[510][maxn];

int main()
{
    scanf("%d",&T);
    while(T--)
    {
        memset(dp,0,sizeof dp);
        scanf("%d%d",&n,&m);

        scanf("%s",s);

        for(int i=1;i<=n/2;i++) a[i]=s[i-1]-‘a‘+1;
        for(int i=n/2;i<=n-1;i++) b[i-n/2+1]=s[i]-‘a‘+1;

        dp[n/2+1][0]=1;
        for(int i=n/2;i>=1;i--)
        {
            if(a[i]==b[i])
            {
                for(int j=0;j<=1000;j++) dp[i][j]=dp[i+1][j];
                for(int j=0;j<=1000;j++) if(dp[i+1][j]==1&&j+2<=1000) dp[i][j+2]=1;
            }

            else
            {
                for(int j=0;j<=1000;j++)
                {
                    if(dp[i+1][j]==1)
                    {
                        if(j+1<=1000) dp[i][j+1]=1;
                        if(j+2<=1000) dp[i][j+2]=1;
                    }
                }
            }
        }

        bool fail=0; int z=m;
        for(int i=1;i<=n/2;i++)
        {
            bool xx=1;
            for(int j=1;j<=26;j++)
            {
                int num=0;
                if(a[i]!=j) num++; if(b[i]!=j) num++;

                if(z-num<0) continue;
                if(dp[i+1][z-num])
                {
                    ans[i]=j;
                    xx=0; z=z-num; break;
                }
            }
            if(xx==1) fail=1;
            if(fail==1) break;
        }

        if(fail) printf("Impossible\n");
        else
        {
            for(int i=1;i<=n/2;i++) printf("%c",ans[i]-1+‘a‘);
            for(int i=1;i<=n/2;i++) printf("%c",ans[i]-1+‘a‘);
            printf("\n");
        }
    }
    return 0;
}
时间: 2024-08-06 16:02:12

HDU 5903 Square Distance的相关文章

hdu 5903 Square Distance(dp)

Problem Description A string is called a square string if it can be obtained by concatenating two copies of the same string. For example, "abab", "aa" are square strings, while "aaa", "abba" are not. Hamming distanc

HDU 5903 Square Distance (贪心+DP)

题意:一个字符串被称为square当且仅当它可以由两个相同的串连接而成. 例如, "abab", "aa"是square, 而"aaa", "abba"不是. 两个长度相同字符串之间的 hamming distance是对应位置上字符不同的位数. 给定一行字符串和 m,输出字典序最小的字符串. 析:首先先用dp判断能不能形成这样的字符串,然后再打印出来,dp[i][j] 表示 i - 中间的数能不能改 j 个字符得到,最后打印

HDU 5903 - Square Distance [ DP ] ( BestCoder Round #87 1002 )

题意: 给一个字符串t ,求与这个序列刚好有m个位置字符不同的由两个相同的串拼接起来的字符串 s, 要求字典序最小的答案    分析: dp[i][j] 表示 第i位及之后的总代价为j可不可行 从第 n/2-1 位推回第 0 位, 若dp[0][m] = 1,则存在 然后贪心对每一位从'a'试到'z',选取接下来存在解的字符 1 #include <cstdio> 2 #include <algorithm> 3 #include <iostream> 4 #inclu

hdu 1398 Square Coins(母函数|完全背包)

http://acm.hdu.edu.cn/showproblem.php?pid=1398 题意:有价值为1^2,2^2....7^2的硬币共17种,每种硬币都有无限个.问用这些硬币能够组成价值为n的钱数共有几种方案数. 母函数: #include <stdio.h> #include <iostream> #include <map> #include <set> #include <stack> #include <vector>

hdu 1518 Square (dfs搜索可参考poj1011)

Square Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 8589    Accepted Submission(s): 2784 Problem Description Given a set of sticks of various lengths, is it possible to join them end-to-end

hdu 1398 Square Coins(母函数,完全背包)

链接:hdu 1398 题意:有17种货币,面额分别为i*i(1<=i<=17),都为无限张, 给定一个值n(n<=300),求用上述货币能使价值总和为n的方案数 分析:这题可以用母函数的思想,对300以内的值进行预处理即可 也可用完全背包思想求300以内的方案数 母函数: #include<stdio.h> int main() { int c1[305],c2[305],i,j,k,n; for(i=0;i<=300;i++){ c1[i]=1; c2[i]=0;

hdu 1518 Square(深搜dfs)

转载请注明出处:http://blog.csdn.net/u012860063?viewmode=contents 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1518 --------------------------------------------------------------------------------------------------------------------------------------------

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"不是. 两个长度相同字

hdu 1518 Square(深搜+剪枝)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1518 题目大意:根据题目所给的几条边,来判断是否能构成正方形,一个很好的深搜应用,注意剪枝,以防超时! 1 #include <iostream> 2 #include <cstdio> 3 #include<algorithm> 4 #include <cstring> 5 using namespace std; 6 int ap[30],visit[30]