HDU 3516 Tree Construction

区间$dp$,四边形优化。

#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<vector>
#include<map>
#include<set>
#include<queue>
#include<stack>
#include<ctime>
#include<iostream>
using namespace std;
typedef long long LL;
const double pi=acos(-1.0),eps=1e-10;
void File()
{
    freopen("D:\\in.txt","r",stdin);
    freopen("D:\\out.txt","w",stdout);
}
template <class T>
inline void read(T &x)
{
    char c = getchar();
    x = 0;
    while(!isdigit(c)) c = getchar();
    while(isdigit(c))
    {
        x = x * 10 + c - ‘0‘;
        c = getchar();
    }
}

int n;
int x[1100],y[1100],dp[1100][1100],f[1100][1100];

int main()
{
    while(~scanf("%d",&n))
    {
        for(int i=1;i<=n;i++) scanf("%d%d",&x[i],&y[i]);
        if(n==1) { printf("0\n"); continue; }

        for(int i=0;i<=n;i++) dp[i][i]=0;
        for(int i=1;i<n;i++)
        {
            dp[i][i+1]=y[i]-y[i+1]+x[i+1]-x[i];
            f[i][i+1]=i;
        }

        for(int len=3;len<=n;len++)
        {
            for(int st=1;st<=n&&st+len-1<=n;st++)
            {
                int en=st+len-1;
                dp[st][en]=0x7FFFFFFF;
                for(int j=f[st][en-1];j<=f[st+1][en];j++)
                {
                    if(dp[st][j]+dp[j+1][en]+y[j]-y[en]+x[j+1]-x[st]<dp[st][en])
                    {
                        dp[st][en]=dp[st][j]+dp[j+1][en]+y[j]-y[en]+x[j+1]-x[st];
                        f[st][en]=j;
                    }
                }
            }
        }

        printf("%d\n",dp[1][n]);
    }
    return 0;
}
时间: 2024-10-27 07:15:50

HDU 3516 Tree Construction的相关文章

【四边形】 HDU 3516 Tree Construction

通道 题意:二维坐标上的点,建一个长度和最小的树包含全部点 思路: 定义状态 dp[i,j]表示点i到点j合并在一起的最小花费(树枝的长度), 状态转移方程:dp[i,j]= min(dp[i,k]+dp[k+1,j]+cost(i,j) ) i<k<j cost(i,j)=py[k]-py[j]+px[k+1]-px[i]; 当j固定时,cost(i,j)单调递减函数 我们猜测cost(i,j)满足四边形不等式 证明: F(i)=cost(i,j+1)-cost(i,j)=py[j]-py[

HDOJ 3516 Tree Construction

四边形优化DP Tree Construction Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 868    Accepted Submission(s): 470 Problem Description Consider a two-dimensional space with a set of points (xi, yi) t

【HDU】3516 Tree Construction

http://acm.hdu.edu.cn/showproblem.php?pid=3516 题意:平面n个点且满足xi<xj, yi>yj, i<j.xi,yi均为整数.求一棵树边只能向上和向右延展的经过所有点的最小长度.(n<=1000, 0<=xi, yi<=10000) #include <cstdio> using namespace std; const int N=1005, oo=~0u>>1; int d[N][N], x[N]

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

hdu 5293 Tree chain problem(树链剖分+树形dp)

题目链接:hdu 5293 Tree chain problem 维护dp[u], sum[u],dp[u]表示以u为根节点的子树的最优值.sum[u]表示以u节点的所有子节点的dp[v]之和.对于边a,b,w,在LCA(a,b)节点的时候进行考虑.dp[u] = min{dp[u], Sum(a,b) - Dp(a,b) + sum[u] | (ab链上的点,不包括u } #pragma comment(linker, "/STACK:1024000000,1024000000")

hdu 5370 Tree Maker(catalan+dp)

题目链接:hdu 5370 Tree Maker n个节点的二叉树种类为Catalan数的第n项 对于一棵子树而言,被移动过的节点就是确定的位置,所以只要知道已经确定位置的K个节点有多少个空孩子指针M,和就该子树下的N个未确定位置的节点,等于是说用N个节点构造M个可为空的子树的种类数.对于整个树的形态数即为若干棵独立的子树形态数的乘积. 定义dp[i][j]为用i个节点构造j棵树的形态数,dp[i][j] = sum{ dp[i-1][j-k] * catalan[k] | 0 ≤ k ≤j }

HDU 5044 Tree(树链剖分)

HDU 5044 Tree 题目链接 就简单的树链剖分,不过坑要加输入外挂,还要手动扩栈 代码: #include <cstdio> #include <cstring> #include <vector> #include <algorithm> using namespace std; const int N = 100005; #pragma comment(linker, "/STACK:1024000000,1024000000"

hdu 4757 Tree(可持久化字典树)

题目链接:hdu 4757 Tree 题目大意:给定一棵树,每一个节点有一个值.如今有Q次询问,每次询问u到v路径上节点值与w亦或值的最大值. 解题思路:刚開始以为是树链剖分,事实上树链剖分仅仅是用来求LCA(能够不用树链剖分). 可持久化字典树.在每次插入的同一时候,不改动原先的节点.而是对全部改动的节点复制一个新的节点,而且在新的节点 上做操作,这样做的目的是可以获取某次改动前的状态.同过可持久化的操作,保留了改动前后的公共数据. 对给定树上的全部节点权值建立01字典树,然后每一个节点都保存

hdu 3534 Tree(树形DP)

题目链接:hdu 3534 Tree 题意: 给你一棵n个节点,n-1条边的树,每条边有一个长度,现在问你最长的边的长度为多少,有多少条. 题解: 其实这种题不用记录最长和次长,我们开两个数组,len[i],num[i]. 表示以i为根结点出发的最长的长度以及最长的边的条数. 然后我们只需要一个dfs,先用子节点的信息来更新答案,然后在更新当前节点的len和num记录的信息. 这样就不用记录最长和次长. 1 #include<bits/stdc++.h> 2 #define mst(a,b)