【轉載】UVa 11464 Even Parity 偶數矩陣

來源:互聯網
上載者:User

標籤:

題意:給你一個n*n的01矩陣,讓你把這個矩陣中盡量少的0轉換成1,使得矩陣每個位置的上下左右四個相鄰的數加起來能被2整除,求最少的轉換數

首先,n 的規模並不大,最大隻有15。但是完全枚舉整個矩陣顯然是不可能的(2225 ≈ 5 * 1067)。但是我們可以枚舉第一行,然後用第一行來算出後面的所有行。

但是,怎麼算呢?

先來說下演算法。對於每一行,我們通過他上面的兩行來決定他的值。如果上面兩行得到值為奇數,那麼這一行就賦值為 1 ,否則賦值為 0 。 然後與原始矩陣比較,如果是由 1 變 0 那麼這種情況是不允許的,於是繼續枚舉第一行,重新計算後面的。如果是由 0  變 1(或不變) 那麼儲存下來。最後在計算所有的格子之後,遍曆一下就能統計轉化數。然後取最小值就可以了。

下面用題目中給的第二組資料來示範一下如何通過上一行來計算下一行。

問題                                        正解

0 0 0                 ==>              0 1 0

1 0 0                 ==>              1 0 1

0 0 0                 ==>              0 1 0

來舉例說明。首先我們通過枚舉第一行可以達到以下情況

0 1 0
     
     

如下表我們開始通過第一行來計算第二行,對於 x 所在的這一格來說,把這一格當做他上面一格的下面相鄰的格子進行計算,於是對於第一行第一列來說,他上下左右相加起來為 1 + x,因為要保證是偶數,所以 x = 1。接著與原矩陣進行比較,是符合題目要求的轉化(不變)。保留,繼續計算下一個。

0 1 0
x    
     

如下表開始計算第二行第二列,按照上面的方法,計算得出 0 + 0 + x 要為偶數,所以 x = 0。與原數組比較依舊是符合題目要求的。

0 1 0
1 x  
     

如下表計算第二行第三列,同上,得出 1 + x 要為偶數,所以 x  = 1。與原矩陣比較,發現是符合要求的轉化(0 變 1)繼續。

0 1 0
1 0 x
     

這樣第二行就得出來了,是下面這種情況:

0 1 0
1 0 1
     

按照上述方法,可以計算出第三行,來完成這個例子的答案:

0 1 0
1 0 1
0 1 0

最後在說一下枚舉第一行的 2 種方法,第一個種自然是直接深度優先搜尋(DP)直接進行枚舉。第二種可以利用位元運算(末尾附上的AC代碼採用的方法)進行枚舉。因為整數在記憶體中是用二進位儲存的。只要讓 s 從 0 開始一直加到 2n-1 – 1 這麼大就可以枚舉所有的情況。

 1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 using namespace std; 5 const int N = 20 + 5; 6 const int INF = (1 << 30) - 1; 7 int a[N][N], dp[N][N],n; 8  9 int deal(int s){10     memset(dp, 0, sizeof(dp));11     for(int c = 0; c < n; c++){12         if(s & (1 << c)) dp[0][c] = 1;13         else if(a[0][c] == 1) return INF;14     }15     for(int r = 1; r < n; r ++){16         for(int c = 0; c < n; c ++){17             int sum = 0;18             if(r > 1) sum += dp[r-2][c];19             if(c > 0) sum += dp[r-1][c-1];20             if(c < n) sum += dp[r-1][c+1];21             dp[r][c] = sum % 2;22             if(dp[r][c] == 0 && a[r][c] == 1)return INF;23         }24     }25     int ret = 0;26     for(int r = 0; r < n; r ++)27         for(int c = 0; c < n; c ++)28             if(a[r][c] != dp[r][c])  ret++;29     return ret;30 }31 32 33 int main(){34     int T;35     scanf("%d", &T);36     for(int cas = 1; cas <= T; cas ++){37         scanf("%d", &n);38         for(int r = 0; r < n; r ++)39             for(int c = 0; c < n; c ++) 40                 scanf("%d", &a[r][c]);41         int ans = INF;42         for(int s = 0; s < (1 << n); s ++)43             ans = min(ans, deal(s));44         printf("Case %d: %d\n", cas, ans == INF ? -1 : ans);45     }46     return 0;47 }

 

【轉載】UVa 11464 Even Parity 偶數矩陣

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.