传送门 poj 3254
题目描述
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: 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)
输出
Line 1: One integer: the number of ways that FJ can choose the squares modulo 100,000,000.
样例
- Input
2 3
1 1 1
0 1 0- Output
9
题解
- 友情翻译一波:农夫有一块地,被划分为m行n列大小相等的格子,其中一些格子是可以种植的(用1标记),农夫可以在这些格子里种上玉米,其他格子则不能种植(用0标记),并且要求不可以使相邻格子都玉米。现在输入数据给出这块地的大小及可否种植的情况,求该农夫有多少种种植方案可以选择(注意:任何格子都不放也是一种选择,不要忘记考虑!
- 思路:
样例第一行状态数:
编号 | 状压(压缩前) | 状态(压缩后) |
---|---|---|
1 | 0 0 0 | 0 |
2 | 0 0 1 | 1 |
3 | 0 1 0 | 2 |
4 | 1 0 0 | 4 |
5 | 1 0 1 | 5 |
- 我们用1表示在这块地上种上了玉米,用0表示没有种植玉米,这样我们就可以用0和1表示每一行的所有状态,也就是每一种状态可以用一个二进制数表示。当我们需要对状态之间进行处理,即判断是否有两块地相邻时,我们判断是否有两个1相邻即可。但这种方法未免太过复杂,并且时间也不允许,所以我们对于每一种状态,用一个十进制数替换掉它所对应的二进制数。
- 当我们要判断一行的某种状态a是否有两个玉米相邻的时候,我们只需要将这个十进制数a左移一位,然后对原来的数进行&运算( a & (a<<1) ),若得到的结果不为0,则有两个玉米相邻。
- 当我们要判断当前行的某种状态a是否与上一行的某种状态b有冲突(即列相邻)时,只需要判断 a & b是否为零即可。
- 我们用dp[i][j]表示第i行第j种可行状态与前面有多少种组合方式,状态转移方程为:dp[i][j]=dp[i-1][k1]+dp[i-1][k2]+…+dp[i-1][kt]。kt为上一行可行方案的编号,共有t种(前提是状态之间不会冲突)。
若第i行有num种可行方案,则从1到i行的总的可行方案就有dp[i][1]+dp[i][2]+…+dp[i][num]种。那么从1到m行的可行方案总和就是dp[m][1]+dp[m][2]+…+dp[m][num]种。
Code
1 |
|