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

            糯米

            TI DaVinci, gstreamer, ffmpeg
            隨筆 - 167, 文章 - 0, 評論 - 47, 引用 - 0
            數據加載中……

            POJ 3123 Ticket to Ride 高效解法

            低效率解法在這里
            低效率的解法是沒法通過POJ的數據的。
            另外一個標程中的解法十分給力,僅用時110ms(status上面還有用時16ms的)
            首先來看一下這段程序:

            #include <iostream>
            #include 
            <string>
            #include 
            <map>

            using namespace std;

            int main()
            {
                
            int INF=99999999,N,K,d[30][30],i,j,k,x,y,z,dp[256][30],e[8],v[30],c,b;
                
            string s,t;    
                
            while (cin >> N >> K && N) {
                    map
            <string,int> cityMap;
                    
            for(i=0;i<N;i++
                        
            for(j=0;j<N;j++
                            d[i][j]
            =i==j?0:INF;
                    
            for(i=0;i<N;i++) {
                        cin 
            >> s;
                        cityMap[s]
            =i;
                    }
                    
            if (K)
                        
            while(cin >> s >> t >> z, x=cityMap[s], 
                                y
            =cityMap[t], 
                                d[x][y]
            =d[y][x]=min(d[y][x],z), --K);
                    
            for(k=0;k<N;k++)
                        
            for(i=0;i<N;i++)
                            
            for(j=0;j<N;j++)
                                d[i][j]
            =min(d[i][j],d[i][k]+d[k][j]);
                    
            for(i=0;i<8;i++) {
                        cin 
            >> s;
                        e[i]
            =cityMap[s];
                        
            for(j=0;j<N;j++)
                            dp[
            1<<i][j]=d[j][e[i]];
                    }        
                    
            for(i=1;i<256;i++) {
                        
            if (!(i&(i-1)))
                            
            continue;
                        
            // step1
                        for(k=0;k<N;k++) {
                            dp[i][k]
            =INF;
                            v[k]
            =0;
                            
            for(j=1;j<i;j++)
                                
            if ((i|j)==i)
                                    dp[i][k]
            =min(dp[i][k],dp[j][k]+dp[i-j][k]);
                        }
                        
            // step2
                        for(j=0;b=INF,j<N;j++) {
                            
            for(k=0;k<N;k++)
                                
            if (dp[i][k]<=&& !v[k])
                                    b
            =dp[i][c=k];
                            
            for(k=0,v[c]=1;k<N;k++)
                                dp[i][c]
            =min(dp[i][c],dp[i][k]+d[k][c]);
                        }
                    }
                    
                    
            // step3
                    for(i=0,b=INF;z=0,i<256;b=min(b,z),i++)
                          
            for(j=0;y=0,j<4;z+=!!y*dp[y][x],j++)
                            
            for(k=0;k<8;k+=2)
                                  
            if ((i>>k&3)==j)
                                    y
            +=3<<k,x=e[k];        
                    
                    cout 
            << b << endl;     
                }
                
            return 0;
            }

            這段程序寫得很讓人費解。花了半天時間我才搞明白。
            實際上大體的思路是跟低效率的解法一樣的。
            就是在求Minimal Steiner Tree這一步,它用了一種新的動態規劃的方法。
            動態規劃的方程為:
            dp[mask][i] = { 以點i為根,包含mask中的點的最小生成樹的權值 }

            在得知 dp[mask - 1][1...N] 的情況下,如何推出 dp[mask][1...N] 呢?
            程序中分為 step1 和 step2 兩個步驟。
            step1 推出:
            a = min{ dp[m1][i] + dp[m2][i] } 其中 m1|m2 = mask
            這個很好理解。
            step2 推出:
            b = min{ dp[mask][j] + d[j][i] }
            程序中每次都從 dp[mask][1...N] 中選出最小的一個 dp[mask][c]
            按這種順序更新就能保證結果的正確
            因此 dp[mask][i] = min(a, b)

            這個動態規劃法的確牛逼。

            step3則是枚舉4條路線的各種組合情況。求出每種組合的MST權值。

            代碼寫得很牛逼。看了半天才看懂。如果讓我寫,行數至少多出2,3倍來。。
            老外就是牛逼,一行代碼都不浪費。

            posted on 2011-02-24 17:16 糯米 閱讀(2052) 評論(1)  編輯 收藏 引用 所屬分類: POJ

            評論

            # re: POJ 3123 Ticket to Ride 高效解法  回復  更多評論   

            你好.我是從你的舊blog找過來的.原來的rfl的代碼鏈接http://gforge.osdn.net.cn/svn/rfl/

            失效了.不知道哪里能找到代碼.
            除了blog.怎樣才能聯系到你?
            我的email: boxer#sina.cn
            2011-03-15 17:22 | sudoers
            国产精品一区二区久久精品| 久久久无码一区二区三区| 国产69精品久久久久9999| 久久99国产精品久久99果冻传媒| 久久久WWW免费人成精品| 久久综合色老色| 国产韩国精品一区二区三区久久| 一本大道久久a久久精品综合| 少妇被又大又粗又爽毛片久久黑人| 精品久久久中文字幕人妻| 久久国产精品一区二区| 国产精品久久久香蕉| 久久er热视频在这里精品| 伊人精品久久久久7777| 久久免费美女视频| 亚洲AV无一区二区三区久久 | 久久综合丁香激情久久| 亚洲日本久久久午夜精品| 久久成人国产精品二三区| 国产毛片欧美毛片久久久| 精品久久久久久99人妻| 国产精品久久久久影视不卡| 伊人久久大香线蕉亚洲| 性高湖久久久久久久久AAAAA| 久久精品一区二区| 国产精品久久久久影视不卡| 日产精品久久久久久久性色| 老男人久久青草av高清| 亚洲一级Av无码毛片久久精品| 久久精品成人免费国产片小草| 久久99热精品| 亚洲欧美日韩精品久久| 久久精品国产99国产精偷| 99麻豆久久久国产精品免费| 久久精品国产久精国产| 久久青草国产精品一区| 久久青青草原精品影院| 久久精品国产亚洲一区二区三区 | 99久久人妻无码精品系列| 久久精品亚洲中文字幕无码麻豆| 久久人人妻人人爽人人爽|