洛谷P2622 關燈問題II(狀態壓縮)

2021-09-28 22:27:47 字數 1757 閱讀 9605

現有n盞燈,以及m個按鈕。每個按鈕可以同時控制這n盞燈——按下了第i個按鈕,對於所有的燈都有乙個效果。按下i按鈕對於第j盞燈,是下面3中效果之一:如果a[i][j]為1,那麼當這盞燈開了的時候,把它關上,否則不管;如果為-1的話,如果這盞燈是關的,那麼把它開啟,否則也不管;如果是0,無論這燈是否開,都不管。

現在這些燈都是開的,給出所有開關對所有燈的控制效果,求問最少要按幾下按鈕才能全部關掉。

前兩行兩個數,n m

接下來m行,每行n個數,a[i][j]表示第i個開關對第j個燈的效果。

乙個整數,表示最少按按鈕次數。如果沒有任何辦法使其全部關閉,輸出-132

1 0 1

-1 1 0

對於20%資料,輸出無解可以得分。

對於20%資料,n<=5

對於20%資料,m<=20

上面的資料點可能會重疊。

對於100%資料 n<=10,m<=100

我們設乙個二進位制數s當第j個燈開著時s的第j位是1關閉時是0,由於n非常小,我們就可以用十進位制數表示出所有狀態,所以我們考慮直接暴力搜尋,對每一種n的狀態進行標記,放進v陣列中判斷,保證每個狀態值找一遍,非常暴力,bfs每次列舉開哪乙個開關,第一次找到狀態為0的時候就是答案,

這樣的話複雜度是o(2

n∗m)

o(2^n*m)

o(2n∗m

)是可以接受的

c od

ecode

code

#include

#define n 1001

#define maxn 1000010

#define inf 0x3f3f3f3f

#define ll long long

#define gtc() getchar()

using

namespace std;

template

<

class

t>

inline

void

read

(t &s)

while

(isdigit

(ch)

) s *

= w;

}inline

void

write

(ll x)

int n, m;

int a[

101]

[101];

struct node

;queue q;

int v[maxn]

;bool *** =0;

intbfs

(int s,

int stp)

elseif(

(a[i]

[j]==-1

)&&!(

(ss &(1

<<

(j -1)

))))

}if(v[ss]

)continue

; node y; y.s = ss, y.stp = x.stp +1;

v[ss]=1

; q.

push

(y);}}

return-1

;}intmain()

int s =(1

<; v[s]=1

;printf

("%d\n"

,bfs

(s,0))

;return0;

}

洛谷 P2622 關燈問題II

洛谷p2622 tag 狀態壓縮 題目大意 n個燈,m個按鈕,每個按鈕都可以控制所有燈,給出每個按鈕對每個燈的影響,求從全開到全關的最短步數。題目分析 每盞燈只有兩個狀態,即開與關,記為0和1,則所有燈的狀態總數為2 n n 3時,有000,001,010,100 對每個狀態單獨分析,可以把每個開關...

洛谷 P2622 關燈問題II

現有n盞燈,以及m個按鈕。每個按鈕可以同時控制這n盞燈 按下了第i個按鈕,對於所有的燈都有乙個效果。按下i按鈕對於第j盞燈,是下面3中效果之一 如果a i j 為1,那麼當這盞燈開了的時候,把它關上,否則不管 如果為 1的話,如果這盞燈是關的,那麼把它開啟,否則也不管 如果是0,無論這燈是否開,都不...

洛谷 P2622 關燈問題II

洛谷傳送門 現有n盞燈,以及m個按鈕。每個按鈕可以同時控制這n盞燈 按下了第i個按鈕,對於所有的燈都有乙個效果。按下i按鈕對於第j盞燈,是下面3中效果之一 如果a i j 為1,那麼當這盞燈開了的時候,把它關上,否則不管 如果為 1的話,如果這盞燈是關的,那麼把它開啟,否則也不管 如果是0,無論這燈...