zoukankan      html  css  js  c++  java
  • 【CODEVS】2800 送外卖

    【算法】最短路(floyd)+状态压缩型动态规划

    【题解】

    经典的TSP问题(货郎担问题):求最小权哈密顿回路(遍历全图点一次且仅一次)。本题稍作改动,先说原TSP问题解法:状压DP。

    状态用二进制表示每个点是否走过(状态也包括最后走的点),状态转移关键在于每个点都有且只有另一个点指向它,所以先可以枚举状态k(按顺序枚举时,后面集合的子集已经全部计算完毕),

    对于每个状态枚举最后到达的节点i,再枚举i的所有邻边节点j,从恰好缺i且最后节点为j的状态转移过来。

    memset(f,0x3f,sizeof(f));//初始化为正无穷 
    f[1][0]=0;//不算起点 
    for(int k=1;k<=(1<<n)-1;k++)
     for(int i=1;i<=n;i++)
      for(int j=1;j<=n;j++)
       if((1<<(i-1))&k)f[i][k]=min(f[i][k],f[j][k-(1<<(i-1))]+mp[j][i]);
    printf("%d",f[1][(1<<n)-1]);
    View Code

    这里有一个细节,设初始状态为f[1][0]=0(起点为1),即起点的初态不包含自身,那么最后f[1][(1<<n)-1]就是答案。

    那么这道题的修改主要是一个城市可以经过多次,那么先跑一遍floyd得出两城市间最短距离后就不必再纠结重复经过的事了。

    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    using namespace std;
    const int maxn=20;
    int n,mp[maxn][maxn],f[maxn][70010];
    int main()
    {
        scanf("%d",&n);n++;
        int x;
        for(int i=1;i<=n;i++)
         {
             for(int j=1;j<=n;j++)
              {
                  scanf("%d",&x);
                  mp[i][j]=x;
              }
         }
        for(int i=1;i<=n;i++)mp[i][i]=0;
        for(int k=1;k<=n;k++)
         for(int i=1;i<=n;i++)
          for(int j=1;j<=n;j++)
           mp[i][j]=min(mp[i][j],mp[i][k]+mp[k][j]);
        memset(f,0x3f,sizeof(f));
        f[1][0]=0;
        for(int k=1;k<=(1<<n)-1;k++)
         for(int i=1;i<=n;i++)
          for(int j=1;j<=n;j++)
           if((1<<(i-1))&k)f[i][k]=min(f[i][k],f[j][k-(1<<(i-1))]+mp[j][i]);
        printf("%d",f[1][(1<<n)-1]);
        return 0;
    }
    View Code
  • 相关阅读:
    Docker Secrets
    Docker swarm 使用服务编排部署lnmp
    Docker Swarm 服务编排之命令
    Docker Swarm应用--lnmp部署WordPress
    How to suppress 'Maybe this is program method' warnings from ProGuard
    ProGuard代码混淆详细攻略
    ProGuard代码混淆技术详解
    Web攻防之XSS,CSRF,SQL注入
    Spring中初始化bean和销毁bean的时候执行某个方法的详解
    数据库事务隔离级别+Spring 声明性事务隔离级别
  • 原文地址:https://www.cnblogs.com/onioncyc/p/6505203.html
Copyright © 2011-2022 走看看