シーズン3オフホリデーチームの牛 - (圧力DPなど)トウモロコシ畑

クリエイティブコモンズライセンス 著作権:帰属、紙ベースを作成するために他人を許可し、(同じライセンスで元のライセンス契約に基づいて用紙配布する必要がありますクリエイティブコモンズ

リンク:https://ac.nowcoder.com/acm/contest/945/E
出典:牛オフネットワーク

タイトル説明

ファーマージョン(12≤1≤Mを1≤N 12以下)NによりMからなる豊かな新しい長方形の牧草地を購入した正方形区画を。彼は正方形の数の牛のためのいくつかのおいしいトウモロコシを栽培したいと考えています。残念ながら、正方形のいくつかは不妊であり、植えすることができません。キャニーFJは牛が互いに近接して食べること嫌い植物にどの正方形を選ぶとき、そう、彼は隣接している四角形を選択避けることを知っています。どの2つの選択された四角は、エッジを共有しません。彼はまだ工場にするためにどの正方形として最終的な選択を行っていません。
非常に開放的な男であること、ファーマージョンは植栽のための正方形を選択する方法のためのすべての可能なオプションを検討したいと考えています。彼はとてもオープンマインド彼は有効なオプションとして何の四角を選択しないと考えるということです!ファーマージョンは彼が植物に正方形を選択することができますいくつかの方法を決定するのに役立ちます。

説明を入力します。

ライン1の2つのスペースで区切られた整数MとN
線2 ... M + 1:行I +1はI牧場の行の各セルを説明し、細胞を植えすることができるかどうかを示すNのスペースで区切られた整数(1肥沃および適切な手段植栽のため、0)は不毛と植栽に適していないことを意味します。

出力説明:

行1:整数:100,000,000の残りの部分で割った代替のFJ総数。

例1

2 3
1 1 1
0 1 0

輸出

9

問題解決のアイデア:

各列の数は、小数111として、小数状態に圧縮され、図7に示すように、この状態で7で示されています。
各ラインの記録ドットは0を植えるのに適している(1よりも便利0以降が便利見られるよう構成はWAは、数ラウンド1の開始と称する、可能な解決策に基づくものとすることができるかどうかを決定する)
上下2列&Bとの競合!= 0を示す
第二行010のように、110(最初はない)と呼ば不可能である、または011(第三のではない)、それが可能である特定の場合で処方か否かさもなければ(ベース&へ)== 0が実現可能表します。

、状態遷移方程式
ソリューションDPの実現可能な数[I] [j]は、i番目の行を示し、jは状態
D P [ ] [ J ] = Σ F インクルード R   A リットル リットル   K   ワット 時間 C 時間 ThinSpace&;&ThinSpace。 A R E   V A リットル D ThinSpace&;&ThinSpace。 F インクルード R ThinSpace&;&ThinSpace。 R インクルード ワット ThinSpace&;&ThinSpace。 - 1   A n個 D ThinSpace&;&ThinSpace。 C インクルード メートル p a t i b l e   f o r   c o n d i t i o n   j d p [ i 1 ] [ k ] DP [I] [J] = \和\ limits_ {\のために、\ \全て\、k個の\は、\であり、有効な\ \ \のために、\、行\ \、I - 1 \そして\ \、互換\ \のため、条件\、J} {DP [I - 1] [K]}

ACコード:

/*
 * Copyright (c) 2019 Ng Kimbing, HNU, All rights reserved. May not be used, modified, or copied without permission.
 * @Author: Ng Kimbing, HNU.
 * @LastModified:2019-06-25 T 11:09:41.155 +08:00
 */
package ACMProblems.QianDaoTi;

import static ACMProblems.ACMIO.*;

/*
 * 链接:https://ac.nowcoder.com/acm/contest/945/E
 * 来源:牛客网
 *
 * ## 题目描述 
 * Farmer John has purchased a lush new rectangular pasture composed of M by N (1 ≤ M ≤ 12; 1 ≤ N ≤ 12) square parcels. He wants to grow some yummy corn for the cows on a number of squares. Regrettably, some of the squares are infertile and can't be planted. Canny FJ knows that the cows dislike eating close to each other, so when choosing which squares to plant, he avoids choosing squares that are adjacent; no two chosen squares share an edge. He has not yet made the final choice as to which squares to plant.
 * Being a very open-minded man, Farmer John wants to consider all possible options for how to choose the squares for planting. He is so open-minded that he considers choosing no squares as a valid option! Please help Farmer John determine the number of ways he can choose the squares to plant.
 * ## 输入描述:
 * Line 1: two space-separated integers M and N
 * Lines 2.. M+1: row I +1 describes each cell in row I of the ranch, N space-separated integers indicating whether the cell can be planted (1 means fertile and suitable for planting, 0 means barren and not suitable for planting).
 * ## 输出描述:
 * Line 1: an integer: FJ total number of alternatives divided by a remainder of 100,000,000.
 * ## 示例1
 * >2 3
 * 1 1 1
 * 0 1 0
 *
 * ## 输出
 * >9
 *
 * ## 解题思路:
 * 将每一行的数都压缩成一个十进制的状态,如 1 1 1的十进制是7,则用7来表示这个状态。
 * 将每行suitable for planting的点记录为0(比1更方便判断是否可以基于这个构造一种可能的solution,一开始记为1, WA了几发,后来发现还是记为0方便)
 * 上下两行会冲突,用 a&b != 0 表示
 * 是否有可能配制成目标情况, 如第二行 0 1 0, 则不可能配成1 1 0 (第一个不行)或是 0 1 1 (第三个不行)或是别的 (base & to) == 0 表示可行。
 */
public class BitDp {
    private static final int MOD = 100000000;
    private static int[] row = new int[13];
    private static int[] validList = new int[400];
    private static int[][] dp = new int[13][400];

    private static int not(int foo) {
        return foo == 0 ? 1 : 0;
    }

    public static void main(String[] args) throws Exception {
        setStream(System.in);
        int rowNum = nextInt();
        int colNum = nextInt();// col Num
        for (int i = 0; i < rowNum; i++)
            for (int j = 0; j < colNum; j++)
                row[i] = (row[i] << 1) | not(nextInt());
        int maxCondition = 1 << 12, k = 0;
        for (int i = 0; i < maxCondition; i++)
            if ((i & (i << 1)) == 0)
                validList[k++] = i;
//        System.out.println(Arrays.toString(validList));
        validList[k] = maxCondition;
        maxCondition = 1 << colNum;
        for (int i = 0; validList[i] < maxCondition; i++)
            if (settable(row[0], validList[i]))
                dp[0][i] = 1;
        for (int r = 1; r < rowNum; r++)
            processRow(r, maxCondition);
        int theLastRow = rowNum - 1;
        int ans = 0;
        for (int i = 0; validList[i] < maxCondition; ++i)
            ans = (ans + dp[theLastRow][i]) % MOD;
        System.out.println(ans);
    }

    private static boolean settable(int base, int to) {
        return (base & to) == 0;
    }

    private static boolean willConflict(int a, int b) {
        return (a & b) != 0;
    }

    private static void processRow(int r, int maxCondition) {
        // for each valid case
        for (int i = 0; validList[i] < maxCondition; i++) {
            if (dp[r - 1][i] == 0)
                continue;
            int tryLastRow = validList[i];
            // is settable
            if (!settable(row[r - 1], tryLastRow))
                continue;
            // list[i] is valid.
            for (int j = 0; validList[j] < maxCondition; j++) {
                int tryThisRow = validList[j];
                if (settable(row[r], tryThisRow) && !willConflict(tryLastRow, tryThisRow))
                    dp[r][j] = (dp[r][j] + dp[r - 1][i]) % MOD;  // += last row valid num
            }
        }
    }
}


おすすめ

転載: blog.csdn.net/weixin_44090305/article/details/93600258