zoukankan      html  css  js  c++  java
  • poj 3311 状压DP

    经典TSP变形


    学到:1、floyd  O(n^3)处理随意两点的最短路

        2、集合的位表示,我会在最后的总结出写出。注意写代码之前一定设计好位的状态。本题中,第0位到第n位分别代表第i个城市,1是已经走过,0没走过

    那么DP方程  :dp[s][i]--当前在城市i。状态为s(s存储的是走过了那些城市)


                3、最后要求形成回路,那么就是min(dp[1<<(n+1)-1][i],dp[0][i])


    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <string>
    #include <iostream>
    #include <cmath>
    #include <map>
    #include <queue>
    using namespace std;
    
    #define ls(rt) rt*2
    #define rs(rt) rt*2+1
    #define ll long long
    #define rep(i,s,e) for(int i=s;i<e;i++)
    #define repe(i,s,e) for(int i=s;i<=e;i++)
    #define CL(a,b) memset(a,b,sizeof(a))
    #define IN(s) freopen(s,"r",stdin)
    
    const int MAXN = 12;
    int dis[MAXN][MAXN];
    int dp[1<<MAXN][MAXN];
    const int INF = 1e9+10;
    int n;
    
    void floyd()
    {
        rep(k,0,n+1)
            rep(i,0,n+1)
                rep(j,0,n+1)
                    dis[i][j]=min(dis[i][k]+dis[k][j],dis[i][j]);
    
    }
    
    int main()
    {
        //IN("poj3311.txt");
        int len;
        while(~scanf("%d",&n) && n)
        {
            rep(i,0,n+1)
                rep(j,0,n+1)
                    dp[i][j]=dis[i][j]=INF;
            rep(i,0,n+1)
                rep(j,0,n+1)
                {
                    scanf("%d",&len);
                    dis[i][j]=min(dis[i][j],len);
                }
            floyd();//求出随意两点的距离
            int S=1<<(n+1);
            rep(i,0,S)
                rep(j,0,n+1)
                {
                        dp[i][j]=INF;
                }
    
            for(int s=0;s<S;s++)//枚举全部的状态
                rep(i,0,n+1)
                {
                    if(s&(1<<(i)))
                        {
                            if(s==(1<<i))dp[s][i]=dis[0][i];
                            else
                            rep(j,0,n+1)
                                if(s&(1<<j) && i!=j)
                                {
                                    dp[s][i]=min(dp[s^(1<<i)][j]+dis[j][i],dp[s][i]);
                                }
                        }
                }
            int ans=INF;
            for(int i=0;i<n+1;i++)
                ans=min(ans,dp[(S-1)][i]+dis[i][0]);
            printf("%d
    ",ans);
        }
        return 0;
    }
    


  • 相关阅读:
    DRF初始准备
    树与二叉树知识点总结(一)
    html牛刀小试
    Python算法黑科技collection模块
    栈和队列知识点总结
    python结束程序的三种技巧
    爬虫01
    Django大结局
    Django报错 Forbidden (CSRF token missing or incorrect.): 解决方法
    Django进阶
  • 原文地址:https://www.cnblogs.com/bhlsheji/p/5114023.html
Copyright © 2011-2022 走看看