• UVA-1347 Tour 动态规划 难以确定的状态


    题目链接:https://cn.vjudge.net/problem/UVA-1347

    题意

    给出按x坐标排序的几个点。
    欲从最左边不回头的走到最右边,然后再返回最左边。
    每个点都要被访问,且只能经过一次。
    问最小路程是多少。
    n<=1000

    思路

    紫书动规学习中。
    首先想到tsp的状压dp(O(n^2*2^n)),发现n超大,这一定不对。
    然后就没有什么正经思路了。

    首先发现每个x坐标都不同,且又存在两条路,
    那么可以把问题转换一下,问两个人从最左走不同节点到达最右的总路程。
    设d(i, j)为走过前i个节点,另一个人现在在j节点时的总路程。
    那么有转移方程 d(i, j)=min(d(i+1, j)+dist[i][i+!], d(i+1, i)+dist[j][i+1])
    边界条件变成d(0, 0)=0; d(n-1, i)=dist[n-1][i]

    顺便一提,动态规划在这里大概写一下经验:

    1. 面对难以分析(转移)的状态,试着规定范围或顺序。
      如dp[i]表示0~i下的代价,dp[i][j]为凸包上点ij连成的线段,分割凸包的从i到j的一部分(规定了上下凸壳)
    2. 通常情况下的区间问题,一般首先通过二分做分析。
      与上面的方法略有相同之处,这里同样可以规定ij的顺序(i在mid左边,j在mid右边),更容易入手。
      二分有着很好的复杂度,我们在不超时的情况下,通过给定的ij顺序甚至可以做任何事情,当然必须考虑合并区间问题。
    3. 在确定状态前,可以分析目标函数来尝试逆推转移方程。
      比如矩阵链乘问题,目标函数是$$ sum p_i p_k p_j $$
      很明显的发现连加,那么转移方程很可能是dp[i][j]=min(dp[i][k]+dp[k][j]+w[i][j])
      如果是连乘可能是dp[i][j]=min(dp[i][k]dp[k][j]w[i][j])
      如果是单个值,方程可能是dp[i][j]=max(S[i][j], dp[i][k], dp[k+1][j])
      甚至是等差比数列,我们可以通过预处理来算dp

    提交过程

    AC

    代码

    #include <cmath>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    const int maxn=1000+20;
    int n, x[maxn], y[maxn];
    double data[maxn][maxn], dist[maxn][maxn];
    double dp(int i, int j){
        if (i==n-1) return dist[j][n-1];
        if (data[i][j]>0) return data[i][j];
        
        data[i][j]=min(dp(i+1, i)+dist[j][i+1], dp(i+1, j)+dist[i][i+1]);
        return data[i][j];
    }
    
    int main(void){
        while (scanf("%d", &n)==1 && n){
            for (int i=0; i<n; i++)
                scanf("%d%d", &x[i], &y[i]);
            for (int i=0; i<n; i++)
                for (int j=i+1; j<n; j++)
                    dist[i][j]=sqrt((x[i]-x[j])*(x[i]-x[j])+(y[i]-y[j])*(y[i]-y[j]));
            memset(data, -1, sizeof(data));
            printf("%.2f
    ", dp(0, 0));
        }
    
        return 0;
    }
    
    Time Memory Length Lang Submitted
    769 None None C++ 5.3.0 2018-08-06 05:10:25
  • 相关阅读:
    PermissionError: [Errno 1] Operation not permitted: '/tmp/tmpg255ml7f' -> '/tmp/jieba.cache'
    远程连接MySql
    Unity 连接MySql数据库
    Unity WIndows语音识别(一)关键字识别
    Mac M1原生(ARM64)Golang dev&debug
    记一次思考:中级开发的突破之道
    深入web workers (上)
    indexDB出坑指南(二)
    html+css展示空白类字符的技巧
    前端冷知识
  • 原文地址:https://www.cnblogs.com/tanglizi/p/9438773.html
Copyright © 2020-2023  润新知