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();
    }
}
原文地址:https://www.cnblogs.com/kirito520/p/6420281.html