• <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>

            Why so serious? --[NKU]schindlerlee

            2010年1月11日星期一.sgu131 pku2411 狀態壓縮動態規劃

            2010年1月11日星期一.sgu131 pku2411
            狀態壓縮動態規劃。

            pku2411:
            給一個m*n(m,n<=11)的棋盤,用1*2和2*1的矩形覆蓋這個棋盤,問有多少中方法對這個棋盤進行
            完全覆蓋。

            這題有組合數學上的公式,但是只能對棋盤上沒有障礙的情況有用,如果遇到有障礙的情況,只能
            利用容斥原理進行計算,但是進行容斥原理的會非常復雜。

            其實一看到數據范圍就應該想到使用位運算的狀態壓縮動態規劃。

            主要的程序是
            a表示要鋪滿的這一行的狀態,b表示的是鋪滿上一行的狀態a產生的下一行狀態。
            然后使用狀態b繼續遞推。
             1 
             2 #include<iostream>
             3 #include<cstdio>
             4 #include<cstdlib>
             5 #include<cstring>
             6 #include<algorithm>
             7 using namespace std;
             8 typedef long long LL;
             9 const int maxint = 0x7fffffff;
            10 const long long max64 = 0x7fffffffffffffffll;
            11 #define bin(i) (1 << i)  /*1左移i位*/
            12 #define emp(a,i) (!(a & bin(i))) /*判斷a的i位是否位0*/
            13 
            14 const int N = 1 << 11;
            15 LL f[N], g[N];
            16 int m, n;
            17 int full;
            18 
            19 void dfs(int a, int b, LL k)
            20 {
            21     if (a == full) {  //將a鋪滿之后形成的所有下一行狀態b的鋪法都有k種
            22         g[b] += k; //產生b的所有狀態求和
            23         return;
            24     }
            25     for (int i = 0; i < m; i++) {
            26         if (emp(a, i)) {
            27             if (i < m - 1 && emp(a, i + 1)) {
            28                 dfs(a | bin(i) | bin(i + 1), b, k);  //橫鋪
            29             }
            30             if (emp(b, i)) {
            31                 dfs(a | bin(i), b | bin(i), k);  //豎鋪
            32             }
            33             break;
            34         }
            35     }
            36 }
            37 
            38 int main()
            39 {
            40   int i, j, k;
            41   while(scanf("%d%d"&m, &n) == 2 && m && n) {
            42       memset(f,0,sizeof(f));
            43       memset(g,0,sizeof(g));
            44       full = (1 << m) - 1;
            45       f[full] = 1;
            46       for (k = 0; k <= n; k++) {
            47           for (i = 0; i <= full; i++) {
            48               if (f[i]) { //如果此行的狀態i可達
            49                   dfs(i, 0, f[i]);
            50               }
            51           }
            52           for (i = 0; i <= full; i++) {
            53               f[i] = g[i];
            54               g[i] = 0;
            55           }
            56       }
            57       cout << f[0<< endl;
            58   }
            59   return 0;
            60 }
            61 

            sgu131:pku2411的加強版
            多了L型的瓷磚。這個最好是自己考慮一下,其實就是比上邊的代碼多了幾行

            const int N = 512;
            LL f[N], g[N];
            int m, n;
            int full;

            void dfs(int a, int b, LL k)
            {
                
            if (a == full) {  //將a鋪滿之后形成的所有下一行狀態b的鋪法都有k種
                    g[b] += k;
                    
            return;
                }
                
            for (int i = 0; i < m; i++) {
                    
            /* 六種鋪法,按以下順序分別是
            a:##  ##  ##  #  #    #
            b:    #    #  #  ##  ##
                     * 
            */
                    
            if (emp(a, i)) {
                        
            if (i < m - 1 && emp(a, i + 1)) {
                            dfs(a 
            | bin(i) | bin(i + 1), b, k);
                            
            if (emp(b, i))
                              dfs(a 
            | bin(i) | bin(i + 1), b | bin(i), k);
                            
            if (emp(b, i + 1))
                              dfs(a 
            | bin(i) | bin(i + 1), b | bin(i + 1), k);
                        }
                        
            if (emp(b, i)) {
                            dfs(a 
            | bin(i), b | bin(i), k);
                            
            if (i > 0 && emp(b, i - 1))
                              dfs(a 
            | bin(i), b | bin(i) | bin(i - 1), k);
                            
            if (i < m - 1 && emp(b, i + 1))
                              dfs(a 
            | bin(i), b | bin(i) | bin(i + 1), k);
                        }
                        
            break;
                    }
                }
            }



            posted on 2010-01-13 22:11 schindlerlee 閱讀(1177) 評論(0)  編輯 收藏 引用 所屬分類: 解題報告

            久久久精品人妻一区二区三区蜜桃| 久久99国产精一区二区三区| 韩国三级中文字幕hd久久精品| 久久99热这里只有精品国产| 亚洲国产婷婷香蕉久久久久久| 精品久久亚洲中文无码| 亚洲欧美日韩久久精品第一区| 国产V综合V亚洲欧美久久| 91麻豆精品国产91久久久久久| 久久无码国产| 久久综合给久久狠狠97色| 亚洲国产精品久久久久久| 中文字幕精品久久| 日本精品久久久中文字幕| 久久这里有精品| 久久久久久a亚洲欧洲aⅴ| 亚洲日韩欧美一区久久久久我| 国产精品久久午夜夜伦鲁鲁| 久久久WWW免费人成精品| 久久久久亚洲av无码专区导航 | 国产91久久综合| 亚洲中文字幕久久精品无码APP| 国产一区二区三精品久久久无广告 | 久久久久无码精品国产| 久久精品一区二区影院| 国产69精品久久久久777| 久久精品免费全国观看国产| …久久精品99久久香蕉国产| 2021最新久久久视精品爱| 久久综合综合久久97色| 久久99精品久久只有精品| 国产精品99久久久精品无码| 日本欧美国产精品第一页久久| 天天久久狠狠色综合| 国产成人无码久久久精品一| 亚洲AV日韩精品久久久久久| 午夜视频久久久久一区| 国产成人久久久精品二区三区| 伊人热人久久中文字幕| 狠狠色丁香婷综合久久| 久久91综合国产91久久精品|