zoukankan      html  css  js  c++  java
  • codevs2800 送外卖

    题目描述 Description

    有一个送外卖的,他手上有n份订单,他要把n份东西,分别送达n个不同的客户的手上。n个不同的客户分别在1~n个编号的城市中。送外卖的从0号城市出发,然后n个城市都要走一次(一个城市可以走多次),最后还要回到0点(他的单位),请问最短时间是多少。现在已知任意两个城市的直接通路的时间。

    输入描述 Input Description

    第一行一个正整数n (1<=n<=15)

    接下来是一个(n+1)*(n+1)的矩阵,矩阵中的数均为不超过10000的正整数。矩阵的i行j列表示第i-1号城市和j-1号城市之间直接通路的时间。当然城市a到城市b的直接通路时间和城市b到城市a的直接通路时间不一定相同,也就是说道路都是单向的。

    输出描述 Output Description

    一个正整数表示最少花费的时间

    样例输入 Sample Input
    3
    0 1 10 10
    1 0 1 2
    10 1 0 10
    10 2 10 0
    样例输出 Sample Output

    8

    数据范围及提示 Data Size & Hint

    1<=n<=15

    分类标签 Tags 

     
     
    正解:状态压缩DP
    解题报告:
      以前一直没打过状压DP,今天打道水题。。。
      显然做之前要floyd预处理出两点之间的最短路。
      然后f[i][s]表示到达i时状态为s的最短路径长度,枚举状态和每次走的两个点就可以了。状态s是一个二进制的方法(状压不都这样吗)
      为什么提前算出最短路是可行的呢?因为显然w[i][j]表示i和j的最短路径,那么至少可以保证经过i和j,即便中间经过了其他的点,也没有关系,反正我们会经过的,所以并不会有问题。
     
     1 //It is made by jump~
     2 #include <iostream>
     3 #include <cstdlib>
     4 #include <cstring>
     5 #include <cstdio>
     6 #include <cmath>
     7 #include <algorithm>
     8 #include <ctime>
     9 #include <vector>
    10 #include <queue>
    11 #include <map>
    12 #include <set>
    13 #ifdef WIN32   
    14 #define OT "%I64d"
    15 #else
    16 #define OT "%lld"
    17 #endif
    18 using namespace std;
    19 typedef long long LL;
    20 const int MAXN = 16;
    21 const int MAXS = (1<<17);
    22 int n;
    23 int w[MAXN][MAXN];
    24 int f[MAXN][MAXS];//f[i][j]表示到达i时状态为j的最小值
    25 
    26 inline int getint()
    27 {
    28        int w=0,q=0;
    29        char c=getchar();
    30        while((c<'0' || c>'9') && c!='-') c=getchar();
    31        if (c=='-')  q=1, c=getchar();
    32        while (c>='0' && c<='9') w=w*10+c-'0', c=getchar();
    33        return q ? -w : w;
    34 }
    35 
    36 inline void solve(){
    37     n=getint();
    38     for(int i=0;i<=n;i++)
    39     for(int j=0;j<=n;j++)
    40         w[i][j]=getint();
    41     for(int k=0;k<=n;k++)//预处理出最短路
    42     for(int i=0;i<=n;i++)
    43         for(int j=0;j<=n;j++)
    44         w[i][j]=min(w[i][j],w[i][k]+w[k][j]);
    45     int end=(1<<(n+1))-1;
    46     memset(f,127/3,sizeof(f)); f[0][0]=0; f[0][1]=0;
    47     for(int i=0;i<=end;i++)//此时状态为i,从from到now
    48     for(int now=0;now<=n;now++)
    49         for(int from=0;from<=n;from++) {
    50         if(from==now) continue;
    51         if( ( (1<<now) | i ) !=i) continue;//当前状态必须要经过i
    52         f[now][i]=min(f[now][i],f[from][i-(1<<now)]+w[from][now]);//之前没到达过now
    53         f[now][i]=min(f[now][i],f[from][i]+w[from][now]);//之前已经到达过now
    54         }
    55     printf("%d",f[0][end]);
    56 }
    57 
    58 int main()
    59 {
    60   solve();
    61   return 0;
    62 }
     
     
  • 相关阅读:
    addddd
    editor
    ui
    java.lang.NoClassDefFoundError: org/apache/poi/poifs/filesystem/FileMagic
    tomcat配置本地域名
    Spring Boot+MyBatis项目搭建
    约瑟夫环问题(100围坐一圈报数,报3出圈)
    java二分查找法
    bootstrap-table数据导出及Checkbox相关设置
    java按给定字节数截取含有中英文的字符串
  • 原文地址:https://www.cnblogs.com/ljh2000-jump/p/5652932.html
Copyright © 2011-2022 走看看