• <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
            數(shù)據(jù)加載中……

            POJ 3123 Ticket to Ride 高效解法

            低效率解法在這里
            低效率的解法是沒法通過POJ的數(shù)據(jù)的。
            另外一個標程中的解法十分給力,僅用時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;
            }

            這段程序?qū)懙煤茏屓速M解。花了半天時間我才搞明白。
            實際上大體的思路是跟低效率的解法一樣的。
            就是在求Minimal Steiner Tree這一步,它用了一種新的動態(tài)規(guī)劃的方法。
            動態(tài)規(guī)劃的方程為:
            dp[mask][i] = { 以點i為根,包含mask中的點的最小生成樹的權(quán)值 }

            在得知 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]
            按這種順序更新就能保證結(jié)果的正確
            因此 dp[mask][i] = min(a, b)

            這個動態(tài)規(guī)劃法的確牛逼。

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

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

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

            評論

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

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

            失效了.不知道哪里能找到代碼.
            除了blog.怎樣才能聯(lián)系到你?
            我的email: boxer#sina.cn
            2011-03-15 17:22 | sudoers
            久久精品天天中文字幕人妻| 久久综合亚洲欧美成人| 99久久精品国产毛片| 99久久免费只有精品国产| 亚洲а∨天堂久久精品| 欧美一区二区三区久久综| 国产精品久久99| 精品久久久一二三区| 久久精品国产男包| 999久久久免费国产精品播放| 亚洲精品国产自在久久| 国产亚洲婷婷香蕉久久精品| 欧美亚洲国产精品久久| 久久美女人爽女人爽| 狠狠精品久久久无码中文字幕| 热久久国产精品| 97精品伊人久久久大香线蕉 | 情人伊人久久综合亚洲| 久久国内免费视频| 国产午夜精品理论片久久| 久久亚洲春色中文字幕久久久| 日本亚洲色大成网站WWW久久| 久久国产一区二区| 久久综合给久久狠狠97色| 久久成人小视频| 无码任你躁久久久久久久| 国产精品欧美亚洲韩国日本久久| 国产亚洲色婷婷久久99精品| 亚洲精品蜜桃久久久久久| 性做久久久久久久久浪潮| 久久精品视频91| 久久av高潮av无码av喷吹| 久久精品一区二区国产| 精品久久久久久亚洲精品| 久久综合精品国产二区无码| 久久成人国产精品| 九九久久99综合一区二区| 久久久九九有精品国产| 99精品伊人久久久大香线蕉| 国产精品久久久久乳精品爆 | 狠狠色伊人久久精品综合网|