zoukankan      html  css  js  c++  java
  • bzoj1087: [SCOI2005]互不侵犯King (codevs2451) 状压dp

    唔...今天学了状压就练练手...

    点我看题

    这题的话,我感觉算是入门题了QAQ...

    然而我还是想了好久...

    大致自己推出了方程,但是一直挂,调了很久选择了题解 坚持不懈的努力的调代码。

    然后发现题解的方程和我一毛一样呀QAQ

    然后就又开始无限调调调QAQ最后发现自己统计答案没放循环里...气哇QAQ看都之后哇的一声哭出来。

    好吧进入正题吧。

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

    然后方程就是  f[i,j,k+num[j]]+=f[i-1,x,k]

    就是枚举一个 x 表示 第 i-1 层的状态,然后判其是否合法。

    刚开始的时候懒的预处理,后来发现预处理代码更短就改了QAQ是的我是懒兔纸

    所以我萌预处理一个 num[i] 表示 状态为 i 中的 1 个数有多少个,也就是放了多少个国王。

    顺便对于 不合法的状态 i 的num[i]=-1

    然后对于枚举的每一个 x 直接暴力判 j 和 x 这两个状态合起来后是否合法。

    暴力判的原因是我懒得预处理QAQ

    然后 就枚举 k 表示 前 i-1 行已经放了 k 个国王。

    辣么k+num[j] 就是第 i 行放完后的个数。

    显然 k 的范围是 num[x]<=k<=m-num[j]

    然后就愉快的水过去了,虽然wa了一次,因为longlong。

    总的来说今天的状态压缩学得还不错=v=

     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
    34   read(n,m);
    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
  • 相关阅读:
    < java.util >-- Set接口
    Codeforces 627 A. XOR Equation (数学)
    Codeforces 161 B. Discounts (贪心)
    Codeforces 161 D. Distance in Tree (树dp)
    HDU 5534 Partial Tree (完全背包变形)
    HDU 5927 Auxiliary Set (dfs)
    Codeforces 27E. Number With The Given Amount Of Divisors (暴力)
    lght oj 1257
    Codeforces 219D. Choosing Capital for Treeland (树dp)
    Codeforces 479E. Riding in a Lift (dp + 前缀和优化)
  • 原文地址:https://www.cnblogs.com/Bunnycxk/p/7467565.html
Copyright © 2011-2022 走看看