题目链接:http://poj.org/problem?id=3185
题意:20盏灯排成一排。操作第i盏灯的时候,i-1和i+1盏灯的状态均会改变。给定初始状态,问最少操作多少盏灯使得所有灯的状态最后均为0.
思路:高斯消元,记录变元个数,枚举变元。
int a[N][N],ans[N]; vector<int> b; int Gauss() { b.clear(); int i,j=1,k,t; for(i=1;i<=20;i++) { for(k=j;k<=20;k++) if(a[k][i]) break; if(k>20) { b.pb(i); continue; } for(t=1;t<=21;t++) swap(a[k][t],a[j][t]); for(t=1;t<=20;t++) if(t!=j&&a[t][i]) { for(k=1;k<=21;k++) a[t][k]^=a[j][k]; } j++; } for(i=j;i<=20;i++) if(a[i][21]) return -1; if(j<=20) return 21-j; for(i=1;i<=20;i++) ans[i]=a[i][21]; return 0; } int main() { int num=0; int i; FOR1(i,20) { RD(a[i][21]); a[i][i]=1; if(i>1) a[i-1][i]=1; if(i<20) a[i+1][i]=1; } int t=Gauss(); if(t==0) { int sum=0; FOR1(i,20) sum+=ans[i]; PR(sum); return 0; } int sum=INF,st,j,k; FOR0(st,(1<<t)) { FOR0(i,t) ans[b[i]]=(st>>i)&1; for(i=20-t;i>=1;i--) { for(j=i;j<=20;j++) if(a[i][j]) break; ans[j]=a[i][21]; for(k=j+1;k<=20;k++) if(a[i][k]) ans[j]^=ans[k]; } int temp=0; FOR1(i,20) temp+=ans[i]; upMin(sum,temp); } PR(sum); }