hdu 3001 Travelling 三進位狀壓Dp

來源:互聯網
上載者:User

題目連結:http://acm.hdu.edu.cn/showproblem.php?pid=3001

附上一個寫的 比較容易理解的連結:http://blog.sina.com.cn/s/blog_6ec19c780100ydws.html

題意:給定幾個城市間的旅遊費用,求把每個城市至少遍曆一遍,且至多兩遍的情況下的至少花費。否則輸出-1。

代碼寫出來之後,會發現和二進位狀壓Dp差不多,只是多了一個附加條件,每個點可以重複一次,所以得用三進位狀態表示,由於電腦中儲存方式不是三進位,所以我們需要預先處理出每種狀態的三進位表示形式,便於枚舉枚舉每個位置的狀態。這就是主要與二進位不同的地方,二進位是直接利用電腦位元運算擷取狀態,相對來說,少了這一過程。

代碼:

<span style="font-size:18px;">#include<iostream>#include<sstream>#include<cstdio>#include<cmath>#include<cstring>#include<algorithm>#include<set>#include<map>#include<queue>#include<vector>#include<string>#define LL long long#define INF 0x7fffffffusing namespace std;int n,m,Map[12][12];int bit[11] = {1,3,9,27,81,243,729,2187,6561,19683,59049};int dp[60000][10],num[60000][11];void init(){//擷取每種狀態的三進位表示形式    for(int i=0;i<bit[10];i++){        int t=i;        for(int j=0;j<10;j++)            num[i][j]=t%3,t/=3;    }}void Dp(){    memset(dp,-1,sizeof(dp));//初始化為-1    for(int i=0;i<n;i++)//把每個起點的費用初始化為0        dp[bit[i]][i]=0;    int ans=-1;    for(int i=0;i<bit[n];i++){//枚舉每一種狀態        int op=1;//所有點都至少遍曆過一次的標誌        for(int j=0;j<n;j++){//和二進位一樣,枚舉每個可以作為起點(即跳轉)的點            if(num[i][j]==0) op=0;            if(dp[i][j]==-1 || num[i][j]==0) continue;//不能跳轉            for(int k=0;k<n;k++){//枚舉可以走的下個點(跳轉目標點)                if(Map[j+1][k+1]==-1 || k==j || num[i][k]>=2) continue;//下一個點不合法                int s=i+bit[k];                if(dp[s][k]==-1) dp[s][k]=dp[i][j]+Map[j+1][k+1];                else dp[s][k]=min(dp[s][k],dp[i][j]+Map[j+1][k+1]);            }        }        if(op){//如果每個點至少遍曆過一次,更新最小費用            for(int j=0;j<n;j++)                if(dp[i][j]!=-1)                    ans=(ans==-1)? dp[i][j]:min(ans,dp[i][j]);        }    }    cout<<ans<<endl;}int main(){    //freopen("D:\\in.txt","r",stdin);    init();    while(cin>>n){        cin>>m;        int a,b,c;        memset(Map,-1,sizeof(Map));        for(int i=0;i<m;i++){            cin>>a>>b>>c;            if(Map[a][b]==-1) Map[a][b]=Map[b][a]=c;            else Map[a][b]=Map[b][a]=min(Map[a][b],c);        }        Dp();    }    return 0;}</span>


聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.