1. 程式人生 > >【狀態壓縮】---狀態壓縮dp第一題

【狀態壓縮】---狀態壓縮dp第一題

標籤: ACM

題目:

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.

Input

Line 1: Two space-separated integers: M and N
Lines 2.. M+1: Line i+1 describes row i of the pasture with N space-separated integers indicating whether a square is fertile (1 for fertile, 0 for infertile)

Output

Line 1: One integer: the number of ways that FJ can choose the squares modulo 100,000,000.

Sample Input

2 3
1 1 1
0 1 0

Sample Output

9

Hint

Number the squares as follows:
1 2 3
4
There are four ways to plant only on one squares (1, 2, 3, or 4), three ways to plant on two squares (13, 14, or 34), 1 way to plant on three squares (134), and one way to plant on no squares. 4+3+1+1=9.

題意:
第一行輸入草地長寬,後面輸入該地方能不能使用,輸出可以使用的所有方案

解題思路
從例題來看第一層有五種可能分別為000,001,010,100,101,都標記為1種可能
第二層可以有000010兩種狀態,但是與上一層比較000與上一層五種狀態都不衝突標記為5種可能,而010與上一層010狀態衝突,所以標記為4種可能
第二層為最底層,將最後一層的可能性全部相加得到9

使用狀態壓縮,將所有可能存在狀態儲存到數組裡面
然後從第一層存在的狀態標記為1
從第二層開始遍歷到最後一層,第二層存在的狀態且不和上一層衝突將上一層的狀態標記加到該層的標記上
遍歷到最後一層時將最後一層的狀態總和加起來就是所有的可能性
注:根據題意答案要對100000000取餘

AC程式碼

#include <iostream>
#include <string.h>
#define M 4100
#define N 15
using namespace std;
int map[N]; //該行的輸入狀態
int m,n;
int dp[N][M];
int p;//該列最大狀態
int s[M];   //儲存每一行擁有的狀態最大4096種狀態
int mod=100000000;
bool checkLine(int i)    //該行是否滿足條件
{
    return !(i&(i>>1));
}
bool checkTwoLine(int i,int j)  //與上一行是否衝突
{
    return !(i&j);
}
bool include(int i,int j)   //是否是包含關係
{
    return ((i|j)==i);
}
void init()
{
    p=0;
    int i,j;
    for(i=0;i<(1<<m);i++)
        if(checkLine(i))
            s[p++]=i;
}
void solve()
{
    int i,j,k;
    int ans=0;
    for(i=0;i<p;i++)
        if(include(map[0],s[i]))
        dp[0][i]=1;

    for(i=1;i<n;i++)
        for(j=0;j<p;j++)    //該行的狀態
        {
            if(!include(map[i],s[j]))
                continue;
            else
                for(k=0;k<p;k++)    //上一行的狀態
            {
                if(include(map[i-1],s[k])&&checkTwoLine(s[j],s[k]))
                    dp[i][j]=(dp[i][j]+dp[i-1][k])%mod;
            }
        }
    for(i=0;i<p;i++)
        ans=(ans+dp[n-1][i])%mod;
    cout<<ans<<endl;
}
int main()
{
    while(cin>>n>>m)
    {
        memset(map,0,sizeof(map));
        int i,j;
        for(i=0;i<n;i++)
            for(j=0;j<m;j++)
            {
                int plant;cin>>plant;
                if(plant){
                    map[i]+=(1<<j);     //將輸入轉換成二進位制儲存
                }
            }
        init();
        solve();
    }

    return 0;
}

相關推薦

狀態壓縮---狀態壓縮dp第一

標籤: ACM 題目: Farmer John has purchased a lush new rectangular pasture composed of M by N (1 ≤ M

狀態壓縮dp第一

tro 兩種 關系 edge sin i+1 第一題 describe 壓縮

經驗分享壓縮PDF檔案操作方法

平常大家處理比較大的檔案的時候,不知道大家是如何進行操作的?在傳輸檔案的時候,有時就是因為檔案太大導致傳輸時間特別長,就拿PDF檔案來說,壓縮PDF檔案我們該如何進行操作呢?下面小編就將自己的方法分享給大家。   1:首先大家可以將需要壓縮的PDF檔案儲存在一個新建的

設計模式狀態模式

模式定義 狀態模式允許物件在內部狀態改變時改變它的行為,物件看起來好像修改了它的類。 下圖是該模式的類圖: 一個生動的例子 就是一個自動售賣機,投硬幣—>搖桿—>出東西。 一共有這麼幾個狀態:無硬幣狀態、有硬幣狀態、無貨狀態和出貨狀態。 下面是程式碼:

Android UI狀態列和toolbar顏色一致

1、在style.xml中定義toolbar的顏色 <resources> <!-- Base application theme. --> <style name="AppBaseTheme" parent="Theme.

設計模式狀態模式和職責鏈的對比

          先簡單的看一下兩個設計模式的官方解釋         Chain ofResponsibility(CoR)模式也叫職責鏈模式或者職責連鎖模式,是行為模式之一,該模式構造一系列分別

NOIP模擬模擬DPJOI2016.11.14第一 複製&貼上2 題解

複製&貼上2(A.c/cpp/pas/in/out) (Time Limit:1s Memory Limit:256MB) 【Description】 文字編輯器的一個最重要的機能就是複製&貼上。JOI社現在正在開發一款能夠非常高速地進行復

LSGDOJ 1333任務安排 dp

包含 機器 bsp pri 時間 一個 cstring getch ons 題目描述 N個任務排成一個序列在一臺機器上等待完成(順序不得改變),這N個任務被分成若幹批,每批包含相鄰的若幹任務。從時刻0開始,這些任務被分批加工,第i個任務單獨完成所需的時間是Ti。在每批任務

BZOJ 2844: albus就是要第一個出場

數組 str 一次 長度 log -c 一個 names 一個數 題目大意:   給一個長度為n的序列,將其子集的異或值排序得到B數組,給定一個數字Q,保證Q在B中出現過,詢問Q在B中第一次出現的下標。 題解:   感覺和hdu3949第K小異或值有一像,然而發現要求

筆記篇斜率優化dp(五) USACO08MAR土地購(征)買(用)Land Acquisition

body 遞增 std char log lin 關鍵字排序 斜率優化 getchar 好好的題目連個名字都不統一.. 看到這種最大最小的就先排個序嘛= =以x為第一關鍵字, y為第二關鍵字排序. 然後有一些\(x_i<=x_{i+1},且y_i<=y_{i+

筆記篇斜率優化dp(一) HNOI2008玩具裝箱

公式 現在 getchar() 就是 clu cst 差距 直接 source 斜率優化dp 本來想直接肝這玩意的結果還是被忽悠著做了兩道數論現在整天渾渾噩噩無心學習甚至都不是太想頹廢是不是藥丸的表現各位要知道我就是故意要打刪除線並不是因為排版錯亂反正就是一個del標簽嘛

筆記篇斜率優化dp(四) ZJOI2007倉庫建設

描述 get -- ons turn clu 最小花費 ont inline 傳送門戳這裏>>> \(n\leq1e6\), 顯然還是\(O(n)\)的做法. 這個題有個條件是只能運往編號更大的工廠的倉庫, 這也是寫出樸素dp的方程的條件. 我們令\(f

筆記篇斜率優化dp(二) SDOI2016征途

不能 最小化 征途 這樣的 string cpp mar logs -s =======傳=送=門======= 搜題目名會搜出很多奇怪的東西... 這個題目似乎有點毒? 比如在bzoj和loj上可以1A的代碼上會在luogu TLE 2個點, 在cogs TLE 10個

筆記篇斜率優化dp(三) APIO2010特別行動隊

tex http span type 2-2 參加 math 就是 裏的 旁聽了一波給舒老師和學弟的pkuwc面試講座... 這裏有一段隱身的吐槽, 想看的請自己想辦法觀看. 不想看的跳過這一段看似空白的東西就好了... 剛開始ATP學姐給我們講了自己面試的時候的事情.

C++ Primer讀書筆記_第一

code 理解 -o 設備 自動 mes 不能 program c++程序 Main():   1. C++程序必須包含main()函數,操作系統通過調用main來運行C++程序。   2. main()的形參可以為空。   3. main函數的返回類型必須為int,返回給

leetcode 簡單 第七十五 第一個錯誤的版本

nbsp 團隊 logs span 通過 bad log 是否 判斷 你是產品經理,目前正在帶領一個團隊開發新的產品。不幸的是,你的產品的最新版本沒有通過質量檢測。由於每個版本都是基於之前的版本開發的,所以錯誤的版本之後的所有版本都是錯的。 假設你有 n 個版本 [1,

URAL - 1114 Boxes (dp,組合數學)

題幹: N boxes are lined up in a sequence (1 ≤ N ≤ 20). You have A red balls and B blue balls (0 ≤ A ≤ 1

*CodeForces - 214D Numbers (dp,組合數學)

題幹: Furik loves writing all sorts of problems, especially such that he can't solve himself. You've got one of his problems, the one Furik gave to

Choosing Capital for Treeland CodeForces - 219D (樹形dp

題目: The country Treeland consists of n cities, some pairs of them are connected with unidirectional roads. Overall there are&n

BZOJ-1237配對(dp

你有n 個整數Ai和n 個整數Bi。你需要把它們配對,即每個Ai恰好對應一 個Bp[i]。要求所有配對的整數差的絕對值之和儘量小,但不允許兩個相同的數配 對。例如A={5,6,8},B={5,7,8},則最優配對方案是5配8, 6配5, 8配7,配對整數 的差的絕對值分別為2, 2, 1,和為5