【区间dp】【四边形不等式】CDOJ1653 最小生成树?

四边形不等式优化的资料去网上找下吧!很多。

可以证明,这个题里面,合并的代价满足较小区间+较大区间<=交错区间。

可以自己画个图看看。

#include<cstdio>
#include<algorithm>
using namespace std;
struct Point{
	int x,y;
}p[1010];
bool cmp(const Point &a,const Point &b){
	return a.x!=b.x ? a.x<b.x : a.y>b.y;
}
int n,f[1010][1010],K[1010][1010];
int main(){
	while(scanf("%d",&n)!=EOF){
		for(int i=1;i<=n;++i){
			scanf("%d%d",&p[i].x,&p[i].y);
		}
		sort(p+1,p+n+1,cmp);
		for(int i=1;i<=n;++i){
			for(int j=i;j<=n;++j){
				f[i][j]=2000000000;
			}
		}
		for(int i=1;i<=n;++i){
			f[i][i]=0;
			K[i][i]=i;
		}
		for(int i=2;i<=n;++i){
			for(int l=1;l+i-1<=n;++l){
				int r=l+i-1;
				for(int k=K[l][r-1];k<=K[l+1][r];++k){
					if(k!=r){
						if(f[l][k]+f[k+1][r]+p[k+1].x-p[l].x+p[k].y-p[r].y<f[l][r]){
							f[l][r]=f[l][k]+f[k+1][r]+p[k+1].x-p[l].x+p[k].y-p[r].y;
							K[l][r]=k;
						}
					}
				}
			}
		}
		printf("%d\n",f[1][n]);
	}
	return 0;
}
时间: 2024-10-11 17:43:40

【区间dp】【四边形不等式】CDOJ1653 最小生成树?的相关文章

区间dp+四边形不等式优化

区间dp+四边形优化 luogu:p2858 题意 给出一列数 \(v_i\),每天只能取两端的数,第 j 天取数价值为\(v_i \times j\),最大价值?? 转移方程 dp[i][j] :n天卖掉i..j货物的收益 dp[begin][end]=max(dp[begin][end-1]+value[end]*(n-len+1) ,dp[begin+1][end]+value[begin]*(n-len+1)); 注意理解 代码 递推形式 #include<bits/stdc++.h>

hdu 3506 Monkey Party 区间dp + 四边形不等式优化

http://acm.hdu.edu.cn/showproblem.php?pid=3506 四边行不等式:http://baike.baidu.com/link?url=lHOFq_58V-Qpz_nTDz7pP9xCeHnd062vNwVT830z4_aQoZxsCcRtac6CLzbPYLNImi5QAjF2k9ydjqdFf7wlh29GJffeyG8rUh-Y1c3xWRi0AKFNKSrtj3ZY7mtdp9n5W7M6BBjoINA-DdplWWEPSK#1 dp[i][j]表示第

hdu 3480 dp 四边形不等式优化

http://acm.hdu.edu.cn/showproblem.php?pid=3480 给出一个数字集合 S,大小为 n,要求把这个集合分成m个子集,每分出一个子集的费用是子集中的 (max-min)^2,求最小费用. 开始的dp转移很容易想到. 首先对集合从小到大排序,dp[i][j] 表示前i个元素被分成j个子集的最小费用.然后枚举最后一个子集. dp[i][j] = min{dp[k-1][j-1] + cost(k, i)}; 这个转移明显是过不去的,n<10000 m<5000

51Nod 1022 石子归并 V2(区间DP+四边形优化)

题目链接:http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1022 题目大意: N堆石子摆成一个环.现要将石子有次序地合并成一堆.规定每次只能选相邻的2堆石子合并成新的一堆,并将新的一堆石子数记为该次合并的代价.计算将N堆石子合并成一堆的最小代价. 例如: 1 2 3 4,有不少合并方法 1 2 3 4 => 3 3 4(3) => 6 4(9) => 10(19) 1 2 3 4 => 1 5 4(5)

[51nod 1022] 石子归并v2 [dp+四边形不等式优化]

题面: 传送门 思路: 加强版的石子归并,现在朴素的区间dp无法解决问题了 首先我们破环成链,复制一条一样的链并粘贴到原来的链后面,变成一个2n长度的序列,在它上面dp,效率O(8n^3) 显然是过不了的,需要优化 注意:dp的转移如下:dp[i][j]=min(dp[i][k]+dp[k+1][j]+sum(i,j)),其中sum(i,j)表示i到j的价值和,满足区间单调性 因此dp[i][j]也满足区间单调性,可以用四边形不等式优化 我们令s[i][j]等于让dp[i][j]取最小值的那个K

HDU-2829 Lawrence (DP+四边形不等式优化)

题目大意:有n个敌方军火库呈直线排列,每个军火库有一个值vi,并且任意相邻的两个库之间都有通道相连.对于任意一条连起来的军火库链,它对我方的威胁可以用函数w(i,j)表示为:w(i,j)=vi*sum(i+1,j)+w(i+1,j)   i<j; w(i,j)=0               i=j; 现在,你有m个炸弹,每颗可以炸掉相邻的两个库之间的通道,求最终的总的最小威胁值. 题目分析:定义状态dp(i,j)表示用 i 颗炸弹使前 j 个库房脱离链条后前 j 个库房产生的最小威胁值,则状态

hdu 2829 dp+四边形不等式优化

用w[i][j]表示i到j之间没有边毁掉的费用. 有一种很好证明w[i][j]是否满足四边形不等式的条件. 若(w[i+1][j]-w[i][j])是关于j的减函数,就是满足条件的.可以证明这里的w[i][j]是瞒住条件的. #include <set> #include <map> #include <queue> #include <stack> #include <cmath> #include <string> #includ

POJ 1160 (区间DP+四边形优化)

这个转移方程不好想,尤其是一段值的解是中间,不明觉厉.dp[i][j] 用i个邮局,覆盖前j个村庄的最小值. 还有就是区间dp的平行四边形优化,这个题的转移方程并不是"区间DP",所以枚举状态要逆着(很花时间),且用一个邮局覆盖都是从0断开了相当于没有断开. 类比于石子归并,矩阵链乘等标准区间DP,其所需状态之前就已经获得,不用倒推 #include <cstdio> #include <cstring> #include <iostream> us

HDU 3516 DP 四边形不等式优化 Tree Construction

设d(i, j)为连通第i个点到第j个点的树的最小长度,则有状态转移方程: d(i, j) = min{ d(i, k) + d(k + 1, j) + p[k].y - p[j].y + p[k+1].x - p[i].x } 然后用四边形不等式优化之.. 1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <algorithm> 5 #include <

hdu3516 Tree Construction (区间dp+四边形优化)

构造方法肯定是把相邻两个点连到一起,变成一个新点,然后再把新点和别的点连到一起.... 设f[i,j]为把第i到j个点都连到一起的代价,那么答案就是f[1,n] f[i,j]=min{f[i,k]+f[k+1,j]+x[k+1]-x[i]+y[k]-y[j]} (画一画就知道了) 然后显然满足四边形不等式(怎么就显然了??) 1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #include&l