zoukankan      html  css  js  c++  java
  • HDOJ 3516 Tree Construction 四边形优化dp

    原题链接:http://acm.hdu.edu.cn/showproblem.php?pid=3516

    题意:

    大概就是给你个下凸包的左侧,然后让你用平行于坐标轴的线段构造一棵树,并且这棵树的总曼哈顿距离最短

    题解:

    很容易得到转移方程:

    $$dp[i][j]=min { dp[i][k-1]+dp[k][j] + dis(uni(i,k-1),uni(k,j))}$$

    其中$dp[i][j]$表示从$i$到$j$的最优解,$dis(i,j)$表示$i$和$j$之间的曼哈顿距离,$uni(i,j)$表示将$i$和$j$用平行于坐标轴的线段连在一起时的拐角点。

    然后可以证明这是满足四边形优化条件的。

    然后四边形优化一下就好。

    代码:

    #include<iostream>
    #include<cstring>
    #include<queue>
    #include<vector>
    #include<algorithm>
    #include<climits>
    #include<cmath>
    #define MAX_N 1234
    #define INF LLONG_MAX/1234
    using namespace std;
    
    typedef long long LL;
    
    LL dp[MAX_N][MAX_N];
    
    int n;
    
    struct point {
    public:
        LL x, y;
    
        point(LL xx, LL yy) : x(xx), y(yy) { }
    
        point() { }
    };
    
    point P[MAX_N];
    
    LL dis(point a,point b){
        return abs(a.x-b.x)+abs(a.y-b.y);
    }
    
    point uni(point a,point b) {
        return point(min(a.x, b.x), min(a.y, b.y));
    }
    
    int s[MAX_N][MAX_N];
    
    int main() {
        cin.sync_with_stdio(false);
        while (cin >> n) {
            for (int i = 1; i <= n; i++)
                cin >> P[i].x >> P[i].y;
            for (int i = 0; i <= n; i++)
                for (int j = 0; j <= n; j++) {
                    if (i == j)
                        dp[i][j] = 0;
                    else
                        dp[i][j] = INF;
                }
            for (int i = 1; i < n; i++)
                dp[i][i + 1] = dis(P[i], P[i + 1]), s[i][i + 1] = i + 1;
            for (int t = 2; t <= n; t++)
                for (int i = 1; i + t <= n; i++) {
                    int j = i + t;
                    int pos = 0;
                    for (int k = s[i][j - 1]; k <= s[i + 1][j]; k++)
                        if (dp[i][j] > dp[i][k - 1] + dp[k][j]+ dis(uni(P[i], P[k - 1]), uni(P[k], P[j])))
                            dp[i][j] = dp[i][k - 1] + dp[k][j] + dis(uni(P[i], P[k - 1]), uni(P[k], P[j])), pos = k;
                    s[i][j] = pos;
                }
            cout << dp[1][n] << endl;
        }
        return 0;
    }
  • 相关阅读:
    Java并发基础知识点总结
    Java中的可重入锁(2)
    Java中的可重入锁
    多线程的共享变量的内存不可见性
    JavaWeb 案例3— Cookie案例
    JavaWeb 案例2—response案例
    JavaWeb 之 三层架构(MVC架构):软件设计架构
    JavaWeb 之 备用9
    JavaWeb 之 备用6
    JavaWeb 之 备用7
  • 原文地址:https://www.cnblogs.com/HarryGuo2012/p/4860581.html
Copyright © 2011-2022 走看看