点灯游戏应该很多人都在小时候頽过吧
反正我直到现在也不会
很明显一个灯最多只需要点一次
然后高斯消元
解完肯定剩自由元(就是那些全是0的行)
然后这些都爆搜
由于剩下的自由元不会太多
所以时间复杂度$O(能过)$
以上
1 #include<cstdio> 2 #include<algorithm> 3 using std::swap; 4 const int N=40; 5 template<typename tp>void read(tp &kk){ 6 tp ret=0,f=1;char ch=getchar(); 7 while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)f=-1;ch=getchar();} 8 while(ch>=‘0‘&&ch<=‘9‘){ret=ret*10+ch-‘0‘;ch=getchar();} 9 kk=ret*f; 10 } 11 int n,a[N][N]; 12 13 14 void gauss() 15 { 16 for(int l=1;l<=n;l++) 17 { 18 int g=l; 19 while(g<=n&&(!a[g][l])) g++; 20 if(g>n) continue; 21 if(l!=g) 22 for(int i=l;i<=n+1;i++) swap(a[l][i],a[g][i]); 23 for(int i=1;i<=n;i++) 24 { 25 if(a[i][l]&&i!=l) 26 { 27 for(int j=l;j<=n+1;j++) a[i][j]^=a[l][j]; 28 } 29 } 30 } 31 } 32 33 int ans; 34 void wtf(int l,int x) 35 { 36 if(x>ans) return; 37 if(!l){ans=x;return;} 38 if(a[l][l]) wtf(l-1,x+a[l][n+1]); 39 else 40 { 41 if(a[l][n+1]) return; 42 wtf(l-1,x); 43 for(int i=l-1;i;i--) a[i][n+1]^=a[i][l]; 44 wtf(l-1,x+1); 45 for(int i=l-1;i;i--) a[i][n+1]^=a[i][l]; 46 } 47 } 48 int m,xi,yi; 49 int main() 50 { 51 read(n),read(m); 52 for(int i=1;i<=n;i++) a[i][i]=a[i][n+1]=1; 53 for(int i=1;i<=m;i++) 54 { 55 read(xi),read(yi); 56 a[xi][yi]^=1,a[yi][xi]^=1; 57 } 58 gauss(); 59 ans=n; 60 wtf(n,0); 61 printf("%d\n",ans); 62 return 0; 63 }
orz
原文地址:https://www.cnblogs.com/rikurika/p/light.html
时间: 2024-11-08 04:18:48