zoukankan      html  css  js  c++  java
  • 【鸽】poj3311 Hie with the Pie[状压DP+Floyd]

    题解网上一搜一大坨的,不用复述了吧。

    只是觉得网上dp方程没多大问题,但是状态的表示含义模糊。不同于正常哈密顿路径求解,状态表示应当改一下。

    首先定义一次移动为从一个点经过若干个点到达另一个点,则$f[S][i]$个人认为应当表示经过若干次移动,每次移动的终点状态记为$1$,由此构成的集合$S$,也就是说,每次移动的中间路过点都不算在内。$i$是最后一次移动的终点。

    下面重点解决两个问题:

    • 为什么不记路过点,状态表示仍然是对的?
    • 不记路过点,走过的一条路,必然可以通过相同的一步一步走的路径把每一步都记成$1$。
    • 怎么处理重复走?
    • 重复走点的时候状态不会变,终止节点会变,但由于状态设计的定义,导致如果这样可以产生更新,则一定可以通过更少的移动来更新出来。

    但是实际上个人理解仍不透彻,所以具体问什么是对的,怎么证明,还尚不清楚。所以人类又要鸽的本质显现。。。

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 #include<cmath>
     6 #define dbg(x) cerr << #x << " = " << x <<endl
     7 using namespace std;
     8 typedef long long ll;
     9 typedef double db;
    10 typedef pair<int,int> pii;
    11 template<typename T>inline T _min(T A,T B){return A<B?A:B;}
    12 template<typename T>inline T _max(T A,T B){return A>B?A:B;}
    13 template<typename T>inline char MIN(T&A,T B){return A>B?(A=B,1):0;}
    14 template<typename T>inline char MAX(T&A,T B){return A<B?(A=B,1):0;}
    15 template<typename T>inline void _swap(T&A,T&B){A^=B^=A^=B;}
    16 template<typename T>inline T read(T&x){
    17     x=0;int f=0;char c;while(!isdigit(c=getchar()))if(c=='-')f=1;
    18     while(isdigit(c))x=x*10+(c&15),c=getchar();return f?x=-x:x;
    19 }
    20 const int N=11;
    21 int f[1<<11][N],dis[N][N];
    22 int n;
    23 
    24 int main(){//freopen("test.in","r",stdin);//freopen("test.ans","w",stdout);
    25     while(read(n),n){
    26         memset(f,0x3f,sizeof f);
    27         for(register int i=0;i<=n;++i)for(register int j=0;j<=n;++j)read(dis[i][j]);
    28         for(register int k=0;k<=n;++k)
    29             for(register int i=0;i<=n;++i)
    30                 for(register int j=0;j<=n;++j)
    31                     MIN(dis[i][j],dis[i][k]+dis[k][j]);
    32         for(register int i=1;i<=n;++i)f[1<<i][i]=dis[0][i];
    33         for(register int i=1;i<1<<n+1;++i)
    34             for(register int j=0;j<=n;++j)if(i&(1<<j))
    35                 for(register int k=0;k<=n;++k)if(k^j)
    36                     MIN(f[i|(1<<k)][k],f[i][j]+dis[j][k]);
    37         printf("%d
    ",f[(1<<n+1)-1][0]);
    38     }
    39     return 0;
    40 }
    View Code

  • 相关阅读:
    solidworks 学习 (二)洗手液瓶
    solidworks 学习 (一)螺丝刀
    tensorflow 2.0 学习(三)MNIST训练
    tensorflow 2.0 学习(二)线性回归问题
    tensorflow 2.0 学习(一)准备
    sscanf linux-c从一个字符串中读进与指定格式相符的数据
    Linux-c glib库hash表GHashTable介绍
    Linux-c给线程取名字
    linux-c getopt()参数处理函数
    golang Linux下编译环境搭建
  • 原文地址:https://www.cnblogs.com/saigyouji-yuyuko/p/11534708.html
Copyright © 2011-2022 走看看