1. 程式人生 > >燈Lights[USACO09NOV]

燈Lights[USACO09NOV]

一個 a20 優化 方案 1-1 ring 亦或 turn inline

題目鏈接:https://www.luogu.org/problemnew/show/P2962

 題解:

  一道高斯消元題,也可以用搜索寫。所以我選擇搜索。

  可以發現每一個開關最多只用操作一次(因為開關兩次等於不動,何必浪費步數呢?),所以我們可以考慮每個開關的狀態,一共有2^n次方種情況,復雜度過高。

  我們考慮一下優化。

  我們將每個開關看做二進制下的一位,將每個開關看做一個數(數的值為自己以及該燈所能到達的燈的二進制的亦或和)。我們舉個例子:樣例中n為5,那麽每個點所對應的二進制位為:1-1(1),2-2(10),3-4(100),4-8(1000),5-16(10000)。因為1點能夠到達的點為2和3,所以1點所對應的值為6(2^4)。

  我們讓一個方案的值為該方案所選的所有點的值的亦或和,那麽當一個方案的值為(2^n-1)時,這個方案就是滿足條件的。

  其實我們不用枚舉所有的方案,用meet in the middle可以使復雜度變為O(sqrt(2^n))。

技術分享圖片
 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<vector>
 5 #include<map>
 6 #define LL long long
 7 #define RI register int
 8
using namespace std; 9 const int INF = 0x7ffffff ; 10 const int N = 40 ; 11 12 inline int read() { 13 int k = 0 , f = 1 ; char c = getchar() ; 14 for( ; !isdigit(c) ; c = getchar()) 15 if(c == -) f = -1 ; 16 for( ; isdigit(c) ; c = getchar()) 17 k = k*10 + c-0 ; 18
return k*f ; 19 } 20 int n, m, lv, ans = INF ; LL hh[N] ; LL tt ; LL p1[N], bin[N] ; 21 bool flag ; 22 map<LL,int>p ; // 開不下2^35的數組,其實最多只有2^18次方個狀態,所以用map 23 24 void dfs(int now,LL res,int used) { 25 if(now > lv) { 26 if(res == tt) { 27 ans = min(ans,used) ; 28 } 29 else { 30 if(!flag) { 31 int t = p[res] ; 32 if(!t || used < t) p[res] = used ; 33 } else { 34 if(p[tt^res]) ans = min(ans,p[tt^res]+used) ; 35 } 36 } 37 return ; 38 } 39 dfs(now+1,res^p1[now],used+1) ; dfs(now+1,res,used) ; // 選與不選 40 } 41 42 int main() { 43 n = read(), m = read() ; 44 bin[0] = 1 ; 45 for(int i=1;i<=n;i++) bin[i] = bin[i-1]<<1 ; 46 tt = bin[n] - 1 ; 47 memset(hh,0,sizeof(hh)) ; 48 LL x, y ; 49 for(int i=1;i<=m;i++) { 50 x = read(), y = read() ; 51 hh[x] ^= bin[y-1], hh[y] ^= bin[x-1] ; 52 } 53 for(int i=1;i<=n;i++) hh[i] ^= bin[i-1] ; 54 lv = n>>1 ; 55 for(int i=1;i<=lv;i++) p1[i] = hh[i] ; 56 dfs(1,0,0) ; // 搜索前一半 57 for(int i=1;i<=n-lv;i++) p1[i] = hh[i+lv] ; 58 lv = (n+1)>>1 ; flag = 1 ; // flag標記在搜索前半段還是後半段 59 dfs(1,0,0) ; // 搜索後一半 60 printf("%d",ans) ; 61 return 0 ; 62 }
View Code

燈Lights[USACO09NOV]