声明:
本篇文章不讲基础,对萌新不太友好,(我就是萌新),要学状压$dp$的请另寻,这篇文章只是便于本人查看。。。。
首先看到$n<=10$,就可以考虑状压了,要求最小值,所以初始化大一点,我们设$f[i]$表示当前状态为$i$的最少按按钮数
所以$f[(1<<n)-1]$初始化为$0$,因为初始状态不需要按按钮。
开始转移状态,我们第一层循环从全开的状态到全关的状态,第二层枚举这次用哪个开关,第三层枚举这次开关的影响。最终状态$f[0]$就是答案,代码如下:
#include<iostream> #include<cstdio> #include<cstring> #define N 11 #define M 101 using namespace std; int n,m; int val[M][N],f[1<<N]; int main() { memset(f,0x3f,sizeof(f)); scanf("%d%d",&n,&m); for(int i=1;i<=m;++i) for(int j=1;j<=n;++j) scanf("%d",&val[i][j]); f[(1<<n)-1]=0; for(int i=(1<<n)-1;i>=0;--i) for(int j=1;j<=m;++j) { int now=i; for(int k=1;k<=n;++k) { if(!val[j][k]) continue; if(val[j][k]==1&&(i&(1<<(k-1)))) now^=1<<(k-1); if(val[j][k]==-1&&!(i&(1<<(k-1)))) now^=1<<(k-1); } f[now]=min(f[now],f[i]+1); } if(f[0]==0x3f3f3f3f) printf("-1"); else printf("%d",f[0]); return 0; }