题目链接:http://poj.org/problem?id=3254
入门的状压DP,看了我一上午~~
其实就是枚举每一位的情况,然后计算下一位与上一位不冲突的情况~~
https://blog.csdn.net/harrypoirot/article/details/23163485
这篇博客写的就挺棒的,就是这篇博客让我明白了这道题。
感谢大佬Rrz。
我的代码(ps:居然1A了):
import java.io.*;
public class Main {
static int state[],stateLen; //表示所有可能状态,长度
static int farmer[]; //表示所有农场的状态
static int dp[][]; //不用解释了吧,你懂的
static int n,m;
public static final int mod=(int) 1e9; //多么华丽漂亮的修饰
static StreamTokenizer in=new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
public static void main(String[] args) throws Exception {
init();
setFarmer();
setState();
setDp();
System.out.println(getAns());
}
static void init() throws Exception{
n=getInt();
m=getInt();
dp=new int[15][1000];
farmer=new int[15];
state=new int[1000];
}
static void setFarmer() throws Exception{
for(int i=0;i<n;i++)
for(int j=0;j<m;j++) {
int a=getInt();
if(a==0) { //按位取反
farmer[i]+=(1<<(m-j-1));
}
}
}
static void setState() {
int total=1<<m;
for(int i=0;i<total;i++)
if(isOk(i))
state[stateLen++]=i;
}
static void setDp() {
for(int i=0;i<stateLen;i++)
if((state[i]&farmer[0])==0)
dp[0][i]=1;
for(int i=1;i<n;i++) {
for(int j=0;j<stateLen;j++) {
if((farmer[i]&state[j])!=0)
continue;
for(int k=0;k<stateLen;k++) {
if((state[j]&state[k])==0)
dp[i][j]=(dp[i][j]+dp[i-1][k])%mod;
}
}
}
}
static int getAns() {
int ans=0;
for(int i=0;i<stateLen;i++)
ans=(ans+dp[n-1][i])%mod;
return ans;
}
static boolean isOk(int x) {
return (x&(x<<1))==0;
}
static int getInt() throws Exception{
in.nextToken();
return (int) in.nval;
}
}