zoukankan      html  css  js  c++  java
  • Gym 101170A Arranging Hat dp

    Arranging Hat

    题目大意:

    给你n,m n个m位的数,保证m位,问要是n个按照从小到大排序,求改变最少个数字,使得这n个按照不递增排序,求最后排序的结果。

    //dp[i][j] 表示前i个数,修改不超过j次的最小值。 dp[i][j]向dp[i+1][j+k]转移
    //pre[i][j]表示第i个数修改j次是由第i-1个数修改pre[i][j]次转移过来的。

    #include <cstdio>
    #include <cstring>
    #include <queue>
    #include <algorithm>
    #include <iostream>
    using namespace std;
    const int maxn=1e5+10;
    typedef long long ll;
    //dp[i][j] 表示前i个数,修改不超过j次的最小值。 dp[i][j]向dp[i+1][j+k]转移
    //pre[i][j]表示第i个数修改j次是由第i-1个数修改pre[i][j]次转移过来的。
    string dp[45][500],unite,str[45];
    int pre[45][500];
    char a[45][500];
    int n,m;
    
    string judge(int x){
        string ans;
        ans.clear();
        for(int i=0;i<m;i++){
            int num=a[1][i]-'0';
            if(num&&x) {
                x--;
                ans+='0';
            }
            else ans+=num+'0';
        }
        return ans;
    }
    bool Min(string u,string v){
        for(int i=0;i<m;i++){
            if(u[i]!=v[i]){
                if(u[i]>v[i]) return false;
                return true;
            }
        }
        return true;
    }
    
    string judge(string ss,int x,int k){
        // printf("k=%d
    ",k);
        string ans;ans.clear();
        int cnt=0,mark=-1,sum=k;
        for(int i=0;i<m;i++){
            ans+=a[x][i];
            if(a[x][i]!=ss[i]) cnt++;
        }
        if(k==0){
            if(Min(ss,ans)==0) return unite;
            return ans;
        } 
    
        if(cnt<=k) return ss;
        for(int i=0;i<m;i++){
            if(a[x][i]!=ss[i]){
                if(k) {
                    k--;
                    ans[i]=ss[i];
                    if(k==0) mark=i;
                }
            }
        }
        // printf("mark=%d
    ",mark);
        if(Min(ss,ans)) return ans;
        for(int i=mark;i>=0;i--){
            if(ans[i]!='9'){
                ans[i]++;
                int flag=0,num=0;
                for(int j=i+1;j<m;j++) ans[j]=a[x][j];
                for(int j=0;j<m;j++){
                    if(ans[j]!=a[x][j]) num++;
                }
                num=sum-num;
                for(int j=i+1;j<m&&num;j++){
                    if(ans[j]-'0'){
                        ans[j]='0';
                        num--;
                    }
                }
                return ans;
            }
        }
        return unite;
    }
    //43435
    //42431
    
    void init(){
        unite.clear();
        for(int i=1;i<=m;i++) unite+='a';
    }
    
    
    int main(){
        scanf("%d%d",&n,&m);init();
        for(int i=1;i<=n;i++){
            scanf("%s",a[i]);
        }
        int len=100;
        for(int i=1;i<=n;i++){
            for(int j=0;j<=len;j++){
                dp[i][j]=unite;
            }
        }
    //    printf("len=%d
    ",len);
        for(int i=0;i<=len;i++) dp[1][i]=judge(i);
        for(int i=1;i<n;i++){
            for(int j=0;j<=len;j++){
                for(int k=0;k+j<=len;k++){
                    string tmp=judge(dp[i][j],i+1,k);
                    // printf("i=%d j=%d k=%d
    ",i,j,k);
                    // cout<<dp[i][j]<<endl;
                    // cout<<tmp<<endl;
                    if(Min(dp[i+1][j+k],tmp)==0){
                        // printf("i=%d j=%d k=%d
    ",i,j,k);
                        // cout<<dp[i][j]<<endl;
                        // cout<<dp[i+1][j+k]<<endl;
                        // cout<<tmp<<endl;
                        dp[i+1][j+k]=tmp;
                        pre[i+1][j+k]=j;
                        // printf("pre[%d][%d]=%d
    ",i+1,j+k,j);
                    }
                }
            }
        }
        //printf("www
    ");
        int mark=0;
        for(int i=0;i<=len;i++){
    //        printf("i=%d ",i);
        //    cout<<dp[n][i]<<endl;
            if(Min(unite,dp[n][i])==0){
                mark=i;
                break;
            }
        }
        // printf("%d
    ",mark);
        for(int i=n;i>=1;i--){
            str[i]=dp[i][mark];
            mark=pre[i][mark];
        }
        for(int i=1;i<=n;i++) cout<<str[i]<<endl;
        return 0;
    }
    
    /*
    5 4 
    9999
    0000
    9999
    0000
    9999
    */
    View Code
  • 相关阅读:
    [ 字典树题目 ]
    AC Challenge [ ACM-ICPC 2018 南京赛区网络预赛 ] [dfs + 二进制记忆化搜索 ]
    ACM-ICPC 2018 南京赛区网络预赛 J.Sum [ 类打表 ]
    Bzoj 3224.普通平衡树 [ 权值线段树 ]
    IP:网际协议
    网络概述
    HashSet
    idea中git各颜色文件含义
    keytool证书管理
    openssl证书管理
  • 原文地址:https://www.cnblogs.com/EchoZQN/p/11625862.html
Copyright © 2011-2022 走看看