• <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 糯米 閱讀(2051) 評論(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
            国内精品久久久久影院日本| 亚洲综合婷婷久久| 欧美精品九九99久久在观看| 97久久国产露脸精品国产| 久久国产亚洲精品无码| 久久国产精品久久精品国产| 久久乐国产精品亚洲综合| 久久国语露脸国产精品电影| 久久97精品久久久久久久不卡| 国产一区二区精品久久岳| 人妻精品久久无码专区精东影业| 夜夜亚洲天天久久| 亚洲精品国产字幕久久不卡 | Xx性欧美肥妇精品久久久久久| 久久99精品久久久久久噜噜| 国产精品久久久久久久久软件 | 97久久久久人妻精品专区| 9191精品国产免费久久| 无码任你躁久久久久久久| 久久91精品国产91| 久久精品一区二区国产| 久久99久国产麻精品66| 久久久久国产精品嫩草影院 | 国产精品成人久久久久三级午夜电影 | 国产精品成人久久久久三级午夜电影| 精品伊人久久大线蕉色首页| 久久性生大片免费观看性| 久久综合九色综合欧美狠狠| 国产麻豆精品久久一二三| 久久综合精品国产二区无码| 欧美精品丝袜久久久中文字幕 | 久久久久综合网久久| 精品久久人妻av中文字幕| 亚洲国产精品无码成人片久久| 欧美午夜精品久久久久久浪潮| 国产亚州精品女人久久久久久 | avtt天堂网久久精品| 久久丫精品国产亚洲av不卡 | 久久婷婷五月综合97色直播| 久久久久综合国产欧美一区二区| 77777亚洲午夜久久多喷|