蒙德里安的梦想
import java.io.*;
import java.util.*;
public class Main{
static int N=12;
static int M=(int)(1<<N);
public static void main(String[] args)throws IOException{
BufferedReader in=new BufferedReader(new InputStreamReader(System.in));
long[][] f=new long[N][M];
boolean[] st=new boolean[M];
String[] strs;
while(true){
strs=in.readLine().split(" ");
int n=Integer.parseInt(strs[0]);
int m=Integer.parseInt(strs[1]);
if(n==0&&m==0)break;
//首先先初始化一下从0到1<<n中那些数字有连续奇数个0,st[i]表示i是否有相应连续奇数个0
//st[i]=true表示没有连续奇数个0,反之则有。
for(int i=0;i<1<<n;i++){
int cnt=0;
st[i]=true;
for(int j=0;j<n;j++){
if((i>>j&1)==1){
if((cnt&1)==1)
st[i]=false;
cnt=0;
}
else cnt++;
}
if((cnt&1)==1)st[i]=false;
}
for(int i=0;i<N;i++)Arrays.fill(f[i],0);
f[0][0]=1;
for(int i=1;i<=m;i++)
for(int j=0;j<1<<n;j++)
for(int k=0;k<1<<n;k++)
if((j&k)==0&&st[j|k])
f[i][j]+=f[i-1][k];
System.out.println(f[m][0]);
}
}
}
最短Hamilton路径
import java.io.*;
import java.util.*;
public class Main{
static int N=20;
static int M=1<<N;
static int[][] w=new int[N][N];
static int[][] f=new int[M][N];
public static void main(String[] args)throws IOException{
BufferedReader in=new BufferedReader(new InputStreamReader(System.in));
int n=Integer.parseInt(in.readLine());
for(int i=0;i<n;i++){
String[] strs=in.readLine().split(" ");
for(int j=0;j<n;j++)
w[i][j]=Integer.parseInt(strs[j]);
}
for(int i=0;i<M;i++)Arrays.fill(f[i],0x3f3f3f3f);
f[1][0]=0;
for(int i=0;i<1<<n;i++)
for(int j=0;j<n;j++)
if(((i>>j)&1)==1)
for(int k=0;k<n;k++)
if(((i>>k)&1)==1)
f[i][j]=Math.min(f[i][j],f[i-(1<<j)][k]+w[k][j]);
System.out.println(f[(1<<n)-1][n-1]);
}
}