luogu2622 狀壓DP 關燈問題II

2021-10-23 13:35:33 字數 1395 閱讀 4300

題目描述

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

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

輸入格式

前兩行兩個數,n m

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

輸出格式

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

輸入輸出樣例

輸入 #1

3

21 0 1

-1 1 0

輸出 #1
2
說明/提示

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

對於20%資料,n<=5

對於20%資料,m<=20

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

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

解題思路

設f []

ff[

]為最少按動開關數

f [s

]f[s]

f[s]

為所有燈的狀態為s

ss,『0』表示關,『1』表示開

以蝦請配合程式食用

維護狀態時為什麼用的是異或(^)呢?

異或(^):兩個不同則為1

dep ^=(1

<<

(j -1)

);

第j

jj盞是1,其它位都是0

^計算時

如果其它位原本就開的,那麼1^0得出1,還是開著的

如果其它位原本是關的,那麼0^0得出0,還是關著的

當前位是開著的,1^1得出0,變成關著的

code

#include 

#include

#include

using namespace std;

int n, m, dep, f[

1<<11]

,a[110][

15];int main()

f[dep]

=min

(f[dep]

, f[s]+1

);//動態轉移}if

(f[0]!=

1061109567

)//如果轉移到了全關

printf

("%d"

, f[0]

);else

printf

("-1");

}

洛谷P2622 關燈問題II BFS 狀壓

有m mm個開關和n nn盞燈,第i ii個開關要麼可以開啟第j jj盞燈,要麼可以關上第j jj盞燈,要麼不對第j jj盞燈起作用。求把n nn盞燈全部開啟的最少步數。這道題很明顯可以用bfs bfsbf s做。因為對於每一種情況,我們也就只有m mm種轉移方法,而求的是最優解。而最多只有10盞燈...

洛谷P2622 關燈問題II BFS 狀壓

有mm 個開關和n n盞燈,第i i個開關要麼可以開啟第j j盞燈,要麼可以關上第j j盞燈,要麼不對第j j盞燈起作用。求把n n盞燈全部開啟的最少步數。這道題很明顯可以用bfs bfs做。因為對於每一種情況,我們也就只有m m種轉移方法,而求的是最優解。而最多只有10盞燈,所以可以想到用狀壓。這...

狀壓dp 洛谷P2622

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