zoukankan      html  css  js  c++  java
  • [状压DP]从一个点走过每一个点(旅行商问题)

    A.收集纸片

    Description

    链接:https://ac.nowcoder.com/acm/contest/5713/A
    来源:牛客网

    我们把房间按照笛卡尔坐标系进行建模之后,每个点就有了一个坐标。
    假设现在房子里有些纸片需要被收集,收集完纸片你还要回归到原来的位置,你需要制定一个策略来使得自己行走的距离最短。
    你只能沿着 x 轴或 y 轴方向移动,从位置 (i,j) 移动到相邻位置 (i+1,j),(i-1,j),(i,j+1) 或 (i,j-1) 距离增加 1。

    Input

    在第一行中给出一个T,1≤T≤10T, 1 le T le 10T,1T10, 代表测试数据的组数。
    对于每组输入,在第一行中给出房间大小,第二行给出你的初始位置。
    接下来给出一个正整数 n,1≤n≤10n,1 le n le 10n,1n10 代表纸片的个数。
    接下来 n 行,每行一个坐标代表纸片的位置。
    保证房间小于 20×2020 imes 2020×20,纸片一定位于房间内。

    Output

    对于每组输入,在一行中输出答案。
    格式参见样例。

    Examples

    Input1
    10 10
    1 1
    4
    2 3
    5 5
    9 4
    6 5

    Output

    The shortest path has length 24

    正确解法:

    设dp[i][j]  i是目前走过的点集合(状态),j是最后一个点。

    枚举每一个状态。

    在枚举最后一个点。

    若状态中有这个点,开始压缩

    枚举所有点。

    更新状态。

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cmath>
     4 #include <algorithm>
     5 #include <set>
     6 #include <queue>
     7 #include <stack>
     8 #include <string>
     9 #include <cstring>
    10 #include <vector>
    11 #include <map>
    12 //#include <unordered_map>
    13 #define mem( a ,x ) memset( a , x ,sizeof(a) )
    14 #define rep( i ,x ,y ) for( int i = x ; i<=y ;i++ )
    15 #define lson  l ,mid ,pos<<1
    16 #define rson mid+1 ,r ,pos<<1|1
    17 using namespace std;
    18 typedef long long ll ;
    19 typedef pair<int ,int> pii;
    20 typedef pair<ll ,int> pli;
    21 const int inf = 0x3f3f3f3f;
    22 const ll mod=998244353;
    23 const int N=1e5+50;
    24 int T,k1,k2,n;
    25 int rk[15];
    26 int dis[1<<12][15];
    27 struct node
    28 {
    29     int xx,yy;
    30 }a[15];
    31 int check(node a,node b)
    32 {
    33     return abs(a.xx-b.xx)+abs(a.yy-b.yy);
    34 }
    35 int main()
    36 {
    37     scanf("%d",&T);
    38     while(T--)
    39     {
    40         scanf("%d%d",&k1,&k2);
    41         scanf("%d%d",&a[0].xx,&a[0].yy);
    42         scanf("%d",&n);
    43         for(int i=1;i<=n;i++)
    44             scanf("%d%d",&a[i].xx,&a[i].yy);
    45         for(int i=0;i<=1<<11;i++)
    46             for(int j=0;j<=10;j++)
    47                 dis[i][j]=inf;
    48         for(int i=1;i<=n;i++)
    49             dis[1<<(i-1)][i]=check(a[0],a[i]);
    50         for(int s=0;s<(1<<n);s++)
    51         {
    52             for(int j=1;j<=n;j++)
    53                 if(s&(1<<(j-1)))
    54             {
    55                 for(int k=1;k<=n;k++)
    56                     if(s&(1<<(k-1)))
    57                 {
    58                     dis[s][j]=min(dis[s][j],dis[s^(1<<(j-1))][k]+check(a[k],a[j]));
    59                 }
    60             }
    61         }
    62         int ans=inf;
    63         for(int i=1;i<=n;i++)
    64             ans=min(ans,dis[(1<<n)-1][i]+check(a[0],a[i]));
    65         printf("The shortest path has length %d
    ",ans);
    66 
    67     }
    68 
    69     return 0;
    70 }
    View Code
  • 相关阅读:
    tuple元组
    list列表
    OS模块
    time模块/datetime模块/calendar模块
    Codeforces Round #196 (Div. 2)
    【HDU 2853】 KM算法
    【HDU1914 The Stable Marriage Problem】稳定婚姻问题
    【HDU4585 Shaolin】map的经典运用
    【HDU4578 Transformation】线段树
    【HDU4632 Palindrome subsequence】区间dp
  • 原文地址:https://www.cnblogs.com/Kaike/p/12919480.html
Copyright © 2011-2022 走看看