1087: [SCOI2005]互不侵犯King
Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 1499 Solved: 872
[Submit][Status]
Description
在N×N的棋盘里面放K个国王,使他们互不攻击,共有多少种摆放方案。国王能攻击到它上下左右,以及左上左下右上右下八个方向上附近的各一个格子,共8个格子。
Input
只有一行,包含两个数N,K ( 1 <=N <=9, 0 <= K <= N * N)
Output
方案数。
Sample Input
3 2
Sample Output
16
HINT
Source
题解:
终于A了这道题。。。
其实意识到对安放的国王总个数有限制,那就应该是DP了
又因为是在棋盘上,所以以每行为状态进行转移
又因为n很小,所以状压DP。。。
主要是做一些预处理
代码:
1 var tot,n,i,j1,j2,j,k,l:longint; 2 s:ansistring; 3 ans:int64; 4 a:array[0..1000,0..1000] of boolean; 5 f:array[0..10,0..1000,0..100] of longint; 6 can:array[0..1000] of boolean; 7 calc:array[0..1000] of longint; 8 function check(x,y:longint):boolean; 9 var s1,s2:ansistring; 10 i:longint; 11 begin 12 s1:=binstr(x,n); 13 s2:=binstr(y,n); 14 for i:=1 to n do 15 if (s1[i]='1') and ((s2[i-1]='1') or (s2[i]='1') or (s2[i+1]='1')) then exit(false); 16 exit(true); 17 end; 18 function cann(x:longint):boolean; 19 var s:ansistring; 20 i:longint; 21 begin 22 s:=binstr(x,n); 23 for i:=2 to n do if (s[i]='1') and (s[i]=s[i-1]) then exit(false); 24 exit(true); 25 end; 26 27 procedure init; 28 begin 29 readln(n,k); 30 tot:=1<<n-1; 31 for i:=0 to tot do 32 begin 33 calc[i]:=0; 34 s:=binstr(i,n); 35 for j:=1 to n do if s[j]='1' then inc(calc[i]); 36 end; 37 fillchar(f,sizeof(f),0); 38 for i:=0 to tot do f[1,i,calc[i]]:=1; 39 for i:=0 to tot do 40 if cann(i) then can[i]:=true; 41 for i:=0 to tot do 42 if can[i] then 43 for j:=0 to tot do 44 if can[j] then 45 if check(i,j) then a[i,j]:=true; 46 //for i:=1 to tot do writeln(can[i],' ',calc[i]); 47 end; 48 procedure main; 49 begin 50 for i:=2 to n do 51 for j1:=0 to tot do 52 if can[j1] then 53 for l:=calc[j1] to k do 54 for j2:=0 to tot do 55 if (can[j2]) and (a[j1,j2]) then 56 inc(f[i,j1,l],f[i-1,j2,l-calc[j1]]); 57 // for i:=1 to n do 58 // for j:=0 to tot do 59 // for l:=1 to n do writeln(f[i,j,l]); 60 ans:=0; 61 for i:=0 to tot do if can[i] then inc(ans,f[n,i,k]); 62 writeln(ans); 63 end; 64 begin 65 assign(input,'input.txt');assign(output,'output.txt'); 66 reset(input);rewrite(output); 67 init; 68 main; 69 close(input);close(output); 70 end.