public int minCostBottomUpPaintHouse2(int[][] costs) {
        if (costs.length == 0 || costs[0].length == 0) {
            return 0;
        }
        int[][] dp = new int[costs.length][costs[0].length];
        for (int i = 0; i < costs[0].length; i++) {
            dp[0][i] = costs[0][i];
        }

        for (int i = 1; i < costs.length; i++) {
            Pair p = findMinSecondMin(dp[i - 1]);
            for (int j = 0; j < costs[0].length; j++) {
                dp[i][j] = costs[i][j];
                if (j == p.minIndex) {
                    dp[i][j] += dp[i-1][p.secondMinIndex];
                } else {
                    dp[i][j] += dp[i-1][p.minIndex];
                }
            }
        }
        int min = Integer.MAX_VALUE;
        for (int i = 0; i < dp[0].length; i++) {
            min = Math.min(min, dp[dp.length - 1][i]);
        }
        return min;
    }
Paint House
https://leetcode.com/problems/paint-house/
https://leetcode.com/problems/paint-house-ii/
src/com/interview/dynamic/PaintHouse.java