【ACWing】327. Corn Field

Subject address:

https://www.acwing.com/problem/content/329/

Farmer John’s land by M × NM\times NM×It is composed of N small squares, and now he wants to grow corn in the land. It is a pity that part of the land is sterile and cannot be planted. Moreover, adjacent land cannot be planted with corn at the same time, which means that there will be no common edge between all the squares where corn is planted. Now given the size of the land, please find out how many planting methods there are. Planting nothing on the land is a method.

Input format:
No. 1 11 line contains two integersMMM andNNN . No.2,..., M + 1 2,...,M+12,...,M+1 line: each line containsNNN integers0 00 or1 11 , used to describe the condition of the entire land,1 11 means the land is fertile,0 00 means that the land is sterile.

Output format:
output total planting method to 1 0 8 10^8108 The value after the modulus.

Data range:
1 ≤ M, N ≤ 12 1≤M,N≤121M,N12

The idea is dynamic programming, which can enumerate by row, and store the corn planting status of each row in a state compression method. For example, we can use the binary digits of an integer to enumerate whether corn is planted at each position, 1 11 means species,0 00 means no species. In addition, if you also use an arrayAAA- likeiii number of binary bits to storeiiThe land condition of row i ,1 11 means it cannot be planted,0 00 means energy, then theiiThe valid states of row i are those that are related toA[i] A[i]A [ i ] does the AND operation equals0 00 and not with thei − 1 i-1i1 line of contradictory state. Letf [i] [s] f[i][s]F [ I ] [ S ] Shi firstiiThe planting status of row i isssIn the case of s, how many kinds of planting schemes are there. Then according to thei − 1 i-1iAccording to the planting status of 1 row, there are: f [i] [s] = ∑ (t → s) ∧ (s & A [i] = 0) f [i − 1] [t] f[i][ s]=\sum_{(t\to s)\land (s\& A[i]=0)} f[i-1][t]f[i][s]=(ts)(s&A[i]=0)f[i1 ] [ t ] Initial conditionsf [0] [0] = 1 f[0][0]=1f[0][0]=1 . code show as below:

#include <iostream>
#include <vector>
using namespace std;

const int N = 15, M = 1 << 12, mod = 1e8;
int n, m;
int a[N], f[N][M];
// state存每行的合法状态(即没有两个连续的1的状态),
// head存state[i]能转移到的合法状态(即没有矛盾的状态)
vector<int> state, head[M];

bool check(int st) {
    
    
    for (int i = 0; i < n - 1; i++)
        if ((st >> i & 1) && (st >> i + 1 & 1))
            return false;
    return true;
}

int main() {
    
    
    cin >> m >> n;
    for (int i = 1; i <= m; i++)
        for (int j = 0; j < n; j++) {
    
    
            int s;
            cin >> s;
            a[i] += !s << j;
        }

    for (int i = 0; i < 1 << n; i++)
        if (check(i))
            state.push_back(i);

    for (int i = 0; i < state.size(); i++)
        for (int j = 0; j < state.size(); j++) {
    
    
            int a = state[i], b = state[j];
            if (!(a & b)) head[i].push_back(j);
        }

    f[0][0] = 1;
    for (int i = 1; i <= m; i++)
        for (int cur = 0; cur < state.size(); cur++)
            for (int prev : head[cur])
                if (!(state[cur] & a[i]))
                    f[i][cur] = (f[i][cur] + f[i - 1][prev]) % mod;
    
    int res = 0;
    for (int i = 0; i < state.size(); i++) res = (res + f[m][i]) % mod;

    cout << res << endl;

    return 0;
}

Time complexity O (m 2 2 n) O(m2^{2n})O(m22 n ), it’s actually not so high, because the legal status of the line is much smaller than2 n 2^n2n , spaceO (m 2 n) O(m2^n)O(m2n)

Guess you like

Origin blog.csdn.net/qq_46105170/article/details/114513928