AOJ 2254: Fastest Route

問題: Fastest Route | Aizu Online Judge

解法: ステージが最大で16しかないので、ある時点でのクリア状況は最大で216通りしかない。 各状態についてDPで解いてやれば良い。bitDPと呼ばれているらしい。

解答コード:

import java.io.IOException;
import java.util.Arrays;

public class Main {

    public static void main(String[] args) throws IOException {
        while (true) {
            int N = nextInt();// ステージの数
            if (N == 0) {
                break;
            }
            int[][] stages = new int[N][N + 1];// ステージ攻略にかかる時間
            for (int i = 0; i < stages.length; i++) {
                for (int j = 0; j < stages[i].length; j++) {
                    stages[i][j] = nextInt();
                }
            }

            int[] dp = new int[1 << N];// 全パターン数は2のN乗通り。
            Arrays.fill(dp, Integer.MAX_VALUE);
            dp[0] = 0;

            for (int bit = 0; bit < dp.length; bit++) {
                for (int j = 0; j < N; j++) {
                    if (((bit >> j) & 1) == 0) {
                        // jステージをクリアしていない時、jステージ攻略の最速タイムを考える。
                        int min = stages[j][0];// とりあえずまずは装備無しを考えておく。
                        for (int k = 0; k < N; k++) {
                            if (((bit >> k) & 1) == 1) {
                                // kステージをクリアしてる時のjステージ攻略タイムと比べて短い方をもっておく
                                min = Math.min(min, stages[j][k + 1]);
                            }
                        }
                        dp[bit + (1 << j)] = Math.min(dp[bit + (1 << j)],
                                dp[bit] + min);
                    }
                }
            }
            System.out.println(dp[dp.length - 1]);
        }

    }

    static int nextInt() {
        int c;
        try {
            c = System.in.read();
            while (c != '-' && (c < '0' || c > '9'))
                c = System.in.read();
            if (c == '-')
                return -nextInt();
            int res = 0;
            while (c >= '0' && c <= '9') {
                res = res * 10 + c - '0';
                c = System.in.read();
            }
            return res;
        } catch (IOException e) {
            e.printStackTrace();
        }
        return -1;
    }

    static char nextChar() {
        try {
            int b = System.in.read();
            while (b != -1 && (b == ' ' || b == '\r' || b == '\n'))
                ;
            if (b == -1)
                return 0;
            return (char) b;
        } catch (IOException e) {
        }
        return 0;
    }

}