博客咕咕咕了很久了,是時候寫一下了spa
AcWing 95 費解的開關code
首先能夠看出ci
1.每個位置頂多只會操做一次。由於若是操做兩次的話,至關於不操做,必然是不知足最優解
2.在一套方案中,操做的順序可有可無。
3.若是咱們肯定了第I行的操做方案的話,那麼後面的行數均可以依此遞推,下面給出一個詳細的解答。get
11011
10110
01111
11111
好比說這個例子,若是咱們肯定了第1行,那麼第二行全部的0(座標:a[i][j])
都只能是第三行a[i+1][j]來修改了,由於若是你第二行修改的話,那麼第一行將會打亂,下面每一行依此類推。博客
而後再利用狀態壓縮,就能夠了it
#include <bits/stdc++.h> using namespace std; int n,m,i,j,k,a[7][7],ans1=1e6,b[7][7]; void read() { getchar(); for (i=1; i<=5; i++) { for (j=1; j<=5; j++) { char ch=getchar(); b[i][j]=ch-'0'; } getchar(); } } int main() { int n; cin>>n; while(n--) { read(); for (i=0; i<=(1<<5); i++) { for (j=1; j<=5; j++) { for (k=1; k<=5; k++) a[j][k]=b[j][k]; } int ans=0; for (j=1; j<=5; j++) if (i>>(j-1) & 1) { ans++; a[1][j-1]^=1,a[1][j+1]^=1,a[1][j]^=1,a[2][j]^=1; } for (j=1; j<=4; j++) for (k=5; k>=1; k--) if (!a[j][k]) { ans++; a[j][k]^=1,a[j+2][k]^=1,a[j+1][k]^=1,a[j+1][k+1]^=1,a[j+1][k-1]^=1; } bool ok=true; for (j=1; j<=5; j++) for (k=1; k<=5; k++) if (!a[j][k]) ok=false; if (ok) ans1=min(ans1,ans); } if (ans1>6) cout<<-1<<'\n'; else cout<<ans1<<'\n'; ans1=1e10; } return 0; }