luogu p2622關燈問題II
阿新 • • 發佈:2018-12-06
pac ont 之一 打開 con 表示 std -- ace
luogu p2622關燈問題II
題目描述
現有n盞燈,以及m個按鈕。每個按鈕可以同時控制這n盞燈——按下了第i個按鈕,對於所有的燈都有一個效果。按下i按鈕對於第j盞燈,是下面3中效果之一:如果a[i][j]為1,那麽當這盞燈開了的時候,把它關上,否則不管;如果為-1的話,如果這盞燈是關的,那麽把它打開,否則也不管;如果是0,無論這燈是否開,都不管。
現在這些燈都是開的,給出所有開關對所有燈的控制效果,求問最少要按幾下按鈕才能全部關掉。
輸入輸出格式
輸入格式:
前兩行兩個數,n m
接下來m行,每行n個數,a[i][j]表示第i個開關對第j個燈的效果。
輸出格式:
一個整數,表示最少按按鈕次數。如果沒有任何辦法使其全部關閉,輸出-1
#include<iostream> #include<cstdio> #include<cstring> using namespace std; int n,m,a[110][11],f[1<<11],ans=0x3f3f3f3f; int read() { int n=0,f=1;char c=getchar(); while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();} while(c>='0'&&c<='9'){n=n*10+c-'0';c=getchar();} return n*f; } int main() { n=read(),m=read(); for(int i=1;i<=m;++i) for(int j=1;j<=n;++j) a[i][j]=read(); memset(f,0x3f,sizeof(f)); f[(1<<n)-1]=0; for(int i=(1<<n)-1;i>0;--i) { for(int j=1;j<=m;++j) { int lpk=i; for(int k=1;k<=n;++k) { if(a[j][k]==0)continue; if(a[j][k]==1&&(i&(1<<(k-1))))lpk^=(1<<(k-1)); if(a[j][k]==-1&&!(i&(1<<(k-1))))lpk^=(1<<(k-1)); } f[lpk]=min(f[lpk],f[i]+1); } } if(f[0]>10000000)f[0]=-1; cout<<f[0]; return 0; }
luogu p2622關燈問題II