• HDU 4385 Moving Bricks [状态压缩DP]


      有N个点,每次可以从起点出发到1或者2个点然后回到起点,问走过所有的点需要的最小路程(路程定义为欧氏距离的平方)。

      显然,到一个点路径为S->i->S,到两个点走过的路径为S->i->j->S。状态压缩然后枚举即可。因为和顺序无关,每次只要枚举最小的没有走的点,然后枚举到这个点返回或者到这个点再去另一个点之后返回的路径长度,相同的状态取最小值即可。

      

     1 #include <string.h>
     2 #include <stdio.h>
     3 #include <algorithm>
     4 #define INF 0x3f3f3f3f
     5 #define MAXS 1100000
     6 using namespace std;
     7 struct pnt{int x, y;}p[25];
     8 int n, cas, ans[25], anss;
     9 int d[MAXS], pre[MAXS], dis[25][25];
    10 
    11 int lowbit(int x){return x&-x;}
    12 bool cmp(const int& x, const int& y) {return lowbit(x) < lowbit(y);}
    13 int sqr(int x){return x * x;}
    14 int getdis(pnt p1, pnt p2){return sqr(p1.x - p2.x) + sqr(p1.y - p2.y);}
    15 int main(){
    16     //freopen("test.in", "r", stdin);
    17     scanf("%d", &cas);
    18     for (int ca = 1; ca <= cas; ca++) {
    19         scanf("%d%d", &p[0].x, &p[0].y);
    20         scanf("%d", &n);
    21         for (int i = 1; i <= n; i++) scanf("%d%d", &p[i].x, &p[i].y);
    22         for (int i = 0; i <= n; i++) for (int j = 0; j <= n; j++) dis[i][j] = getdis(p[i], p[j]);
    23         int full = 1<<n;
    24         for (int i = 1; i < full; i++) d[i] = INF;
    25         for (int s = 0; s < full; s++) {
    26             for (int i = 0 ;i < n; i++) if(0 == (s&1<<i)){
    27                 if(d[s|1<<i] > d[s] + 2 * dis[0][i+1]) {
    28                     d[s|1<<i] = d[s] + 2 * dis[0][i+1];
    29                     pre[s|1<<i] = s;
    30                 }
    31                 for (int j = i+1, ss = 1<<i|s; j < n; j++) if(0 == (ss&1<<j)) {
    32                     if (d[ss|1<<j] > d[s] + dis[0][i+1] + dis[i+1][j+1] + dis[j+1][0]) {
    33                         d[ss|1<<j] = d[s] + dis[0][i+1] + dis[i+1][j+1] + dis[j+1][0];
    34                         pre[ss|1<<j] = s;
    35                     }
    36                 }
    37                 break;
    38             }
    39         }
    40         anss = 0;
    41         for (int x = full -1; x != 0; x = pre[x]) {
    42             ans[anss++] = x^pre[x];
    43         }
    44         sort(ans, ans + anss, cmp);
    45         printf("Case %d:\n", ca);
    46         printf("%d\n", d[full - 1]);
    47         for (int i = 0, x = 0; i < anss; i++) {
    48             for (int j = 0; j < n; j++){
    49                 if(ans[i]&1<<j)printf("%d%c", j+1, ++x ==n ? '\n' : ' ');
    50             }
    51 
    52         }
    53     }
    54     return 0;
    55 }
  • 相关阅读:
    这个Pandas函数可以自动爬取Web图表
    /lib64/libstdc++.so.6: version `CXXABI_1.3.8' not found (required by /usr/local/python3.6/lib/python3.6/site-packages/paddle/fluid/core_avx.so)
    kubernetes yaml详解
    centos 安装kubernetes
    初识kafka-connect
    Docker1:本地连接Docker中的mysql,实现数据同步
    git分支管理规范
    cat 配置告警规则
    Java的即时编译(Just In Time, JIT)及其优化
    java自定义实现一个缓存器
  • 原文地址:https://www.cnblogs.com/swm8023/p/2711263.html
Copyright © 2020-2023  润新知