• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            算法學社
            記錄難忘的征途
            posts - 141,comments - 220,trackbacks - 0

            題目描述:

                N(N<100)個帶開關(guān)的燈泡排成一行,每個燈泡的開關(guān)可以轉(zhuǎn)換自己,左邊連續(xù)D個和右邊連續(xù)D個燈泡的開關(guān)狀態(tài)。現(xiàn)在給你每個燈泡的初始狀態(tài){Ai},請問最少開關(guān)多少次能把所有的燈熄滅?

            吐槽:

                1.上來就往DP的思路想是什么水平...
                2.本blog的第一個數(shù)學題目... mark~

            思路分析:

                首先在最后的解中,顯然每個開關(guān)只能按一次。所以貌似可以狀壓DP?,但是由于開關(guān)可以控制后面的燈泡,所以100*2^30果斷GG...
                于是發(fā)現(xiàn)這個可以列出方程組,Xi表示開關(guān)i是否按下,Mij表示開關(guān)i是否可以控制燈泡j:
                    (M00*X0) XOR (M10*X1) XOR ... XOR (M0n-1*Xn-1) = A0
                    (M10*X0) XOR (M11*X1) XOR ... XOR (M1n-1*Xn-1) = A1
                    .              .          ...      .           . .
                    .              .          ...      .           . .
                    .              .          ...      .           . .
                    (Mj0*X0) XOR (Mj1*X1) XOR ... XOR (Mjn-1*Xn-1) = Aj
                
                這個異或方程組怎么解呢? 其實 A XOR B = (A + B) mod 2
                可以看成是同余方程組,那么經(jīng)典的解法就是高斯-約當消元法了...
                其實算的時候還是用XOR操作方便一些...
                這個方程組的解有三種可能:
                    1. 無解: 判斷消元后的系數(shù)矩陣是否存在 0 0 ... 0 1的情況,如果有輸出impossible,否則一定有解。
                    2. 唯一解: 消去的過程中沒有自由變量,即對消去每一列的過程都有主元可以選擇,那么直接向前迭代求出唯一解~
                    3. 無窮解: 存在自由變量,這個時候需要對自由變量進行枚舉,這個復雜度是指數(shù)級的,如果自由變量很少的話是ok的。那么如何估算自由變量呢?
                               矩陣的秩決定了自由變量的個數(shù),不難發(fā)現(xiàn)這個矩陣是非常有特點的,從左到右畫了一個很粗的斜線 :P ,如果n滿足(n>2*D+1)的話,這個矩陣很明顯是滿秩的。
                               否則的話自由變量會在兩行完全相同的情況下出現(xiàn),顯然這種情況下前n列都是1,這樣的行最多會出現(xiàn)D+1次。枚舉次數(shù)最多是2^(D+1),這樣就可以算了~
                
                2和3是可以放在一起寫的哦~
             1 #include<iostream>
             2 #include<cstdio>
             3 #include<cassert>
             4 using namespace std;
             5 #define re(i,n) for(int i =0; i< n; i++)
             6 #define re2(i,n) for(int i =0; i<= n; i++)
             7 const int M = 105;
             8 int gauss[M][M];
             9 int hash[M] , solution[M], P[M], val[M];
            10 template <typename T> inline void chkmin(T &a, const T  b) { if(a > b) a = b;}
            11 int main(){
            12     int t;
            13     cin >> t;
            14     while(t --){
            15         int n,d;
            16         scanf("%d%d",&n,&d);
            17         re(i,n) {
            18             scanf("%d",&gauss[i][n]);
            19         }
            20         int N = 0;
            21         re(i,n) {
            22             re(j,n) gauss[i][j] = 0;
            23             int l = max(0, i - d);
            24             int r = min(n-1, i + d);
            25             for(int j = l; j<= r; j++)
            26                 gauss[i][j] = 1;
            27         }
            28         re(i,n) P[i] = -1 , hash[i] = 0;
            29 //        re(i,n) {re2(j,n) cout << gauss[i][j] << " "; cout<<endl;} cout<<endl;
            30         re(i,n) {
            31             bool flag = 0;
            32             re(j,n) if(!hash[j] && gauss[j][i]){
            33                 P[i] = j;
            34                 flag = hash[j] = 1;
            35                 re(k,n) if(!hash[k] && gauss[k][i])
            36                     for(int x = i; x <= n; x++)
            37                         gauss[k][x] ^= gauss[j][x];
            38                 break;
            39             }
            40             if(!flag) val[N++] = i;
            41         }
            42 //        re(i,n) {re2(j,n) cout << gauss[i][j] << " "; cout<<endl;} cout<<endl;
            43         assert(N <=16);
            44         bool s = 0; int mask = 1 << N;
            45         re(i,n) {
            46             bool flag = 0;
            47             re(j,n) if(gauss[i][j]) flag = 1;
            48             if(!flag && gauss[i][n]) { s = 1; break; }
            49         }
            50         if(s) { puts("impossible"); continue; }
            51         int ans = M;
            52         re(i, mask){
            53             int sum =0;
            54             re(j,N) solution[ val[j] ] = (i & (1 << j)) != 0;
            55             for(int j =n-1 ; j >= 0; j--){
            56                 if(P[j] == -1) continue;
            57                 assert(gauss[P[j]][j]);
            58                 solution[j] = gauss[P[j]][n];
            59                 for(int k = n-1; k>j; k--)
            60                     solution[j] ^= solution[k] & gauss[P[j]][k];
            61             }
            62             re(j,n) sum += solution[j]!=0;
            63             chkmin(ans,sum);
            64         }
            65         cout<<ans<<endl;
            66     }
            67 }
            68 
            posted on 2012-04-27 18:26 西月弦 閱讀(612) 評論(0)  編輯 收藏 引用 所屬分類: 解題報告
            精品国产婷婷久久久| 久久人人爽人人爽人人片AV麻豆 | 久久久无码精品亚洲日韩蜜臀浪潮| 久久综合五月丁香久久激情| 伊人久久大香线蕉精品不卡| 午夜欧美精品久久久久久久| 久久r热这里有精品视频| 中文国产成人精品久久亚洲精品AⅤ无码精品 | 激情综合色综合久久综合| 久久婷婷人人澡人人爽人人爱| 久久免费精品一区二区| 一本久久综合亚洲鲁鲁五月天| 四虎国产精品免费久久5151| 久久精品国产精品亚洲精品 | 久久午夜无码鲁丝片秋霞| 久久精品国产亚洲AV嫖农村妇女| 青青草国产97免久久费观看| 国产精品久久久久aaaa| 99精品国产99久久久久久97| 欧美色综合久久久久久| 久久精品视频免费| 久久国产精品无码HDAV | 亚洲精品tv久久久久久久久久| 97久久超碰国产精品旧版| 伊人色综合久久天天人手人婷| 品成人欧美大片久久国产欧美...| 无码精品久久久天天影视| 久久综合久久伊人| 久久996热精品xxxx| 国产免费久久精品丫丫| 亚洲狠狠久久综合一区77777| 久久成人国产精品| 久久偷看各类wc女厕嘘嘘| 亚洲国产精品无码久久一区二区| 99久久香蕉国产线看观香| 久久本道久久综合伊人| 久久精品国产亚洲一区二区三区| 91精品国产91热久久久久福利 | 国产精品视频久久久| 国内精品久久久久伊人av| 久久er国产精品免费观看2|