# bzoj1087: [SCOI2005]互不侵犯King (codevs2451) 状压dp

f[i,j,k] 表示 放到第 i 行，第 i 行状态为 j 且总共放了 k 个的方案数。

 1 var
2     i,j,k,x:longint;
3     n,m:longint;
4     f:array[0..10,0..1200,0..105]of int64;
5     ans:int64;
6     num:array[0..1200]of longint;
7 function isnot(i,x:longint):boolean;
8 begin
9   exit((1 << (i-1))and x>0);
10 end;
11 function ok(x:longint):longint;
12 var i:longint;
13     num:longint;
14 begin
15   num:=0;
16   for i:=1 to n do
17   begin
18     if isnot(i,x) and((i>1)and isnot(i-1,x)) then exit(-1);
19     if isnot(i,x) then inc(num);
20   end;
21   exit(num);
22 end;
23 function check(x,y:longint):boolean;
24 var i:longint;
25 begin
26   for i:=1 to n do
27   begin
28     if isnot(i,x) then
29       if ((i>1)and(isnot(i-1,y)))or(isnot(i,y))or((i<n)and(isnot(i+1,y))) then exit(false);
30   end;
31   exit(true);
32 end;
33 begin
35   f[0,0,0]:=1;
36   for j:=0 to (1 << n)-1 do
37   num[j]:=ok(j);
38   for i:=1 to n do
39   for j:=0 to (1 << n)-1 do
40   begin
41     if num[j]>=0 then
42     begin
43       for x:=0 to(1 << n)-1 do
44       if (num[x]>=0)and(check(j,x)) then
45       begin
46         for k:=num[x] to m do
47         if k+num[j]<=m then
48           inc(f[i,j,k+num[j]],f[i-1,x,k]);
49       end;
50     end;
51     if i=n then inc(ans,f[i,j,m]);
52   end;
53   writeln(ans);
54 end.
bzoj1087

posted @ 2017-09-02 19:56  Bunnycxk  阅读(188)  评论(0编辑  收藏  举报