zoukankan      html  css  js  c++  java
  • 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
    ");
            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("
    ");
            }
        }
        return 0;
    }
  • 相关阅读:
    poj 2584 T-Shirt Gumbo (二分匹配)
    hdu 1757 A Simple Math Problem (乘法矩阵)
    矩阵之矩阵乘法(转载)
    poj 2239 Selecting Courses (二分匹配)
    hdu 3661 Assignments (贪心)
    hdu 1348 Wall (凸包)
    poj 2060 Taxi Cab Scheme (二分匹配)
    hdu 2202 最大三角形 (凸包)
    hdu 1577 WisKey的眼神 (数学几何)
    poj 1719 Shooting Contest (二分匹配)
  • 原文地址:https://www.cnblogs.com/zufezzt/p/5904896.html
Copyright © 2011-2022 走看看