Water2Wine

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

/*

  • Copyright (c) Huawei Technologies Co., Ltd. 2019-2020. All rights reserved.
    */

/**

  • 状态压缩dp
    */
    public class SC {

    public static void main(String[] args) {
    int[][] grass = {{1,1},{1,1}};
    System.out.println(num(grass));
    }

    // 状态压缩三步走
    private static long num(int[][] grass) {
    // 前置确定:要生成几进制数
    // grass每个土地有七种情况,因此是七进制,移位以3为单位
    // 第一步,获取每一行的地形
    int[] gr = new int[grass.length];
    for (int i = 0;i < gr.length;i++) {
    for (int j = 0;j < grass[0].length;j++) {
    gr[i] = (gr[i] << 3) + grass[i][j];
    }
    }
    // 第二步,获取通用的方案数
    // 如何判断进制的问题还有待商榷
    boolean[] scheme = new boolean[1 << (grass[0].length * 3)];
    for (int i = 0;i < scheme.length;i++) {
    if (isSeven(i) && noSame(i, i << 3)) {
    scheme[i] = true;
    }
    }
    // 第三步,逐行逐方案生成dp
    int[][] dp = new int[grass.length + 1][1 << (grass[0].length * 3)];
    dp[0][0] = 1;
    for (int i = 1;i < dp.length;i++) {
    for (int j = 0;j < dp[0].length;j++) {
    // 要判断两个问题:当前方案是否符合地形,当前方案是否与上一行方案兼容
    if (scheme[j] && isSuit(j, gr[i - 1])) {
    for (int k = 0;k < scheme.length;k++) {
    if (noSame(j, k)) {
    dp[i][j] += dp[i - 1][k];
    dp[i][j] %= 100000000;
    }
    }
    }
    }
    }
    long ans = 0;
    for (int i = 0;i < dp[0].length;i++) {
    ans += dp[dp.length - 1][i];
    ans %= 100000000;
    }
    return ans;
    }
    // 判断i是否是七进制数
    private static boolean isSeven(int i) {
    while (i != 0) {
    if ((i & 7) == 7) {
    return false;
    }
    i = i >> 3;
    }
    return true;
    }
    // 判断i方案和j方案是否有相同的植物
    private static boolean noSame(int i, int j) {
    while (i != 0 && j != 0) {
    if ((i & 7) != 0 && (i & 7) == (j & 7)) {
    return false;
    }
    i = i >> 3;
    j = j >> 3;
    }
    return true;
    }
    // 判断i是否符合地形j
    private static boolean isSuit(int i, int j) {
    // 主要是判断j中000的部分i是否也是000以及不是000的部分是否是000
    while (i != 0 && j != 0) {
    if ((j & 7) == 0 && (i & 7) != (j & 7)) {
    return false;
    } else if ((j & 7) != 0 && (i & 7) == 0) {
    return false;
    }
    i = i >> 3;
    j = j >> 3;
    }
    return true;
    }

}

posted on 2020-08-06 14:03  Water2Wine  阅读(114)  评论(0编辑  收藏  举报