• <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中的點的最小生成樹的權值 }

            在得知 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權值。

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

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

            評論

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

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

            失效了.不知道哪里能找到代碼.
            除了blog.怎樣才能聯(lián)系到你?
            我的email: boxer#sina.cn
            2011-03-15 17:22 | sudoers
            国产成人久久激情91| 亚洲国产成人久久一区久久| 久久久久亚洲Av无码专| 国产精品久久午夜夜伦鲁鲁| 91精品国产高清久久久久久91 | 久久精品亚洲精品国产色婷| 久久九九亚洲精品| 亚洲欧美日韩精品久久亚洲区 | 午夜福利91久久福利| 国内精品伊人久久久影院| …久久精品99久久香蕉国产| 久久国产影院| 国产精品久久久久久一区二区三区| 久久综合视频网站| 国产精品18久久久久久vr| 久久亚洲国产精品123区| 91精品国产综合久久婷婷| 久久青青草原精品国产软件| 精品久久久久久国产潘金莲| 久久久久久一区国产精品| 丰满少妇人妻久久久久久| 国内精品伊人久久久久777| 热RE99久久精品国产66热| 久久se精品一区二区| 欧美va久久久噜噜噜久久| 日韩欧美亚洲综合久久| 激情五月综合综合久久69| 精品无码久久久久久午夜| 色综合久久久久久久久五月| 亚洲伊人久久成综合人影院 | 久久久免费观成人影院| 狠狠干狠狠久久| 蜜臀久久99精品久久久久久小说| 亚洲国产成人久久笫一页| 国产精品成人99久久久久91gav| 久久精品www| 99国内精品久久久久久久 | 伊人久久综合精品无码AV专区| 亚洲AⅤ优女AV综合久久久| 久久久久久A亚洲欧洲AV冫| 久久性精品|