1. 程式人生 > >動態規劃---狀壓dp2

動態規劃---狀壓dp2

mes getc 今天 png 附加 cor ons image namespace

今天模擬,狀壓dp又沒寫出來。。。還是不會啊,所以今天搞一下這個狀壓dp。這裏有一道狀壓dp的板子題:

Corn Fields

就是一道很簡單的狀壓裸題,但是要每次用一個二進制數表示一行的狀態。

附加一個關於位運算的總結:

技術分享圖片

上題幹:

題目描述

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. 農場主John新買了一塊長方形的新牧場,這塊牧場被劃分成M行N列(1 ≤ M ≤ 12; 1 ≤ N ≤ 12),每一格都是一塊正方形的土地。John打算在牧場上的某幾格裏種上美味的草,供他的奶牛們享用。 遺憾的是,有些土地相當貧瘠,不能用來種草。並且,奶牛們喜歡獨占一塊草地的感覺,於是John不會選擇兩塊相鄰的土地,也就是說,沒有哪兩塊草地有公共邊。 John想知道,如果不考慮草地的總塊數,那麽,一共有多少種種植方案可供他選擇?(當然,把新牧場完全荒廢也是一種方案) 輸入輸出格式 輸入格式: 第一行:兩個整數M和N,用空格隔開。 第2到第M
+1行:每行包含N個用空格隔開的整數,描述了每塊土地的狀態。第i+1行描述了第i行的土地,所有整數均為0或1,是1的話,表示這塊土地足夠肥沃,0則表示這塊土地不適合種草。 輸出格式: 一個整數,即牧場分配總方案數除以100,000,000的余數。 輸入輸出樣例 輸入樣例#1: 復制 2 3 1 1 1 0 1 0 輸出樣例#1: 復制 9

題目不用多解釋,直接上代碼,寫註釋了,很好懂。

#include<cstdio>
#include<cstring>
using namespace std;
#define duke(i,a,n) for(int i = a;i <= n;i++)
const int mod = 1e9;
template <class T>
void read(T &x)
{
    char c;
    bool op = 0;
    while(c = getchar(),c > 9 || c < 0)
        if(c == -) op = 1;
    x = c - 0;
    while(c = getchar(),c <= 9&& c >= 0)
        x = x * 10 + c - 0;
    if(op == 1)
        x = -x;
}
int F[15],f[15][4100],m,n,field[15][15];
int state[4110];
int main()
{
    read(m);read(n);
    duke(i,1,m)
        duke(j,1,n)
            read(field[i][j]);
    duke(i,1,m)
    {
        duke(j,1,n)
        {
            F[i] = (F[i] << 1) + field[i][j];//F存i行草地的情況 
        }
    }
    f[0][0] = 1;
    int maxn = 1 << n;
    duke(i,0,maxn - 1)
    {
        state[i] = (((i << 1) & i) == 0) && (((i >> 1) & i) == 0); //每種狀態是否可行 
    }
    duke(i,1,m)
        duke(j,0,maxn - 1)
            if(state[j] && ((j & F[i]) == j)) //j是否能選 
                duke(k,0,maxn - 1)  //上一排能選什麽 
                    if((j & k) == 0)
                        f[i][j] = (f[i][j] + f[i - 1][k]) % mod;
    int ans = 0;
    duke(i,0,maxn - 1)
    {
        ans += f[m][i];
        ans %= mod;
    }
    printf("%d\n",ans);
    return 0;
}

動態規劃---狀壓dp2