• <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 糯米 閱讀(2043) 評論(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
            伊人色综合九久久天天蜜桃| 武侠古典久久婷婷狼人伊人| 国产精品欧美久久久天天影视| 伊人久久大香线蕉av不卡| 国产成人无码久久久精品一| 国产免费久久久久久无码| 亚洲精品tv久久久久久久久久| 亚洲成色WWW久久网站| 欧美色综合久久久久久| 成人国内精品久久久久一区| 婷婷久久综合九色综合九七| 国产精品久久99| 久久久久久久久久久| 99久久精品免费看国产一区二区三区 | 久久久久青草线蕉综合超碰 | 色欲久久久天天天综合网| 色综合久久综合网观看| 中文字幕无码精品亚洲资源网久久| 丁香五月网久久综合| 久久精品人人做人人爽电影蜜月 | 久久国产热精品波多野结衣AV| 久久er国产精品免费观看8| 97热久久免费频精品99| 蜜臀av性久久久久蜜臀aⅴ| 久久天天婷婷五月俺也去| 久久人妻少妇嫩草AV无码蜜桃| 国产三级久久久精品麻豆三级| 久久综合伊人77777| 久久久久久国产精品无码下载| 国产精品久久午夜夜伦鲁鲁| 日韩人妻无码一区二区三区久久99| 久久综合色区| 欧美国产成人久久精品| 中文成人无码精品久久久不卡| 久久精品无码一区二区日韩AV| 国产精品亚洲综合专区片高清久久久 | 国产精品久久久久久一区二区三区 | 久久久亚洲欧洲日产国码是AV| 久久成人18免费网站| 久久精品国产清自在天天线| 久久99精品免费一区二区|