zoukankan      html  css  js  c++  java
  • Codeforces Round #394 (Div. 2)

    题目链接:http://codeforces.com/contest/761/problem/C

    题意:给定n个长度为m的字符串。每个字符串(字符串下标从0到m-1)都有一个指针,初始指针指向第0个位置。现在让你把每个字符串的指针移动到某个位置使得n个字符串中个个字符串的指针指向的字符组成一个新的密码串。并且这个密码串要合法。 一个合法的密码串一个满足:至少有一个数字,一个小写字母,一个给定的符号中的其中一个。问组成合法密码串的最小总移动步数。
    思路:因为只有数字,字母,符号三个要求,并且密码串中都存在一个即可。所以先处理出n个字符串指针移动到这三种的最小步数。然后简单状压dp一下即可。 dp[i][j]表示目前处理到字符串i,状态为j时的最小移动步数(j只有三位分别对应三种要求,当某位为1时说明当前存在这种字符)

    import java.io.PrintWriter;
    import java.util.*;
    
    public class Main {
        public static final int MAXN=50+5;
        public static final int MAXVAL=MAXN;
        public static String str[]=new String [MAXN];
        public static int val[][]=new int [MAXN][3];
        public static int dp[][]=new int [MAXN][(1<<3)];
        public static int getVal(char s){
            if(Character.isDigit(s)==true){
                return 0;
            }
            if(Character.isLowerCase(s)==true){
                return 1;
            }
            return 2;
        }
        public static void main(String[] args) {
            Scanner cin = new Scanner(System.in);
            PrintWriter out = new PrintWriter(System.out);
            int n=cin.nextInt(),m=cin.nextInt();
            for(int i=1;i<=n;i++){
                str[i]=cin.next();
                Arrays.fill(val[i], MAXVAL);
                for(int j=0;j<m;j++){
                    int pos=getVal(str[i].charAt(j));
                    val[i][pos]=Math.min(val[i][pos],Math.min(j,m-j));
                }
            }
            for(int i=0;i<=n;i++){
                Arrays.fill(dp[i], MAXVAL*MAXVAL);
            }
            dp[0][0]=0;
            for(int i=1;i<=n;i++){
                for(int j=0;j<(1<<3);j++){
                    dp[i][j]=dp[i-1][j];
                }
                for(int j=0;j<(1<<3);j++){
                    for(int k=0;k<3;k++){
                        if(((j&(1<<k))==0)&&val[i][k]!=MAXVAL){
                            dp[i][(j|(1<<k))]=Math.min(dp[i][(j|(1<<k))], dp[i-1][j]+val[i][k]);
                        }
                    }
                }
    //            for(int j=0;j<(1<<3);j++){
    //                out.printf("%d ", dp[i][j]);
    //            }
    //            out.println();
            }
            out.println(dp[n][(1<<3)-1]);
            cin.close();
            out.flush();
        }
    }
  • 相关阅读:
    【转】win8.1下安装ubuntu
    Codeforces 1025G Company Acquisitions (概率期望)
    Codeforces 997D Cycles in Product (点分治、DP计数)
    Codeforces 997E Good Subsegments (线段树)
    Codeforces 1188E Problem from Red Panda (计数)
    Codeforces 1284E New Year and Castle Building (计算几何)
    Codeforces 1322D Reality Show (DP)
    AtCoder AGC043C Giant Graph (图论、SG函数、FWT)
    Codeforces 1305F Kuroni and the Punishment (随机化)
    AtCoder AGC022E Median Replace (字符串、自动机、贪心、计数)
  • 原文地址:https://www.cnblogs.com/kirito520/p/6420281.html
Copyright © 2011-2022 走看看