【HDU】3506 Monkey Party

http://acm.hdu.edu.cn/showproblem.php?pid=3506

题意:环形石子合并取最小值= =(n<=1000)

#include <cstdio>
#include <algorithm>
using namespace std;
const int N=2005, oo=~0u>>1;
int a[N], w[N], d[N][N], s[N][N], n;
int main() {
	while(~scanf("%d", &n)) {
		for(int i=1; i<=n; ++i) scanf("%d", &a[i]), a[i+n]=a[i];
		n=2*n;
		int ans=oo;
		for(int i=1; i<=n; ++i) w[i]=w[i-1]+a[i];
		for(int i=1; i<n; ++i) d[i][i+1]=a[i]+a[i+1], s[i][i+1]=i+1;
		for(int len=3; len<=n; ++len) {
			for(int i=1; i<=n-len+1; ++i) {
				int j=i+len-1, l=s[i][j-1], r=s[i+1][j], &now=d[i][j], &pos=s[i][j];
				now=oo;
				for(int k=l; k<=r; ++k) {
					if(now>=d[i][k-1]+d[k][j]) {
						now=d[i][k-1]+d[k][j];
						pos=k;
					}
				}
				now+=w[j]-w[i-1];
			}
		}
		for(int i=1; i<=(n>>1); ++i) ans=min(ans, d[i][i+(n>>1)-1]);
		printf("%d\n", ans);
	}
	return 0;
}

  

妈呀来学了下四边形不等式优化= =

首先对于一类2D2D的方程:

$$
d(i, j)=
\begin{cases}
min \{ d(i, k-1)+d(k, j) \}+w(i, j) & i<j \\
0 & i=j \\
oo & i>j
\end{cases}
$$

(取$max$的我还没分析过,不过我们能将$w(i, j)=-w(i, j)$然后将$max$取$min$就好啦hhh(咦这应该没问题吧?))

我们有下边的定理(证明可以去看论文或者q我= =)

如果$i \le i‘ \le j \le j‘$就有$w(i, j)+w(i‘, j‘) \le w(i‘, j)+w(i, j‘)$(四边形不等式)

且如果$i \le i‘ \le j‘ \le j$就有$w(i‘, j‘) \le w(i, j)$(区间单调性)

设$s(i, j)=max \{ k|d(i, j)=d(i, k-1)+d(k, j)+w(i, j) \}$那么有:

$$
\begin{align}
d(i, j)+d(i‘, j‘) & \le d(i‘, j)+d(i, j‘) \\
s(i, j) \le s(i, j+1) & \le s(i+1, j+1)
\end{align}
$$

而$s$的取值每一个确定的$l=j-i+1$是均摊$O(n)$的(妈呀我看不懂论文上的证明啊= =)所以方程由$O(n^3)$降为$O(n^2)$

于是这题的$sum$显然满足四边形不等式和区间单调性,所以本题成为水题= =

时间: 2024-10-04 17:37:41

【HDU】3506 Monkey Party的相关文章

【HDU】2147 kiki&#39;s game

http://acm.hdu.edu.cn/showproblem.php?pid=2147 题意:n×m的棋盘,每次可以向左走.向下走.向左下走,初始在(1, m),n,m<=2000,问先手是否胜利. #include <cstdio> using namespace std; int main() { int n, m; while(scanf("%d%d", &n, &m), n|m) (n&1)&&(m&1)?

【HDU】4923 Room and Moor(2014多校第六场1003)

Room and Moor Time Limit: 12000/6000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others)Total Submission(s): 263    Accepted Submission(s): 73 Problem Description PM Room defines a sequence A = {A1, A2,..., AN}, each of which is either 0

【HDU】4888 Redraw Beautiful Drawings 网络流【推断解是否唯一】

传送门:pid=4888">[HDU]4888 Redraw Beautiful Drawings 题目分析: 比赛的时候看出是个网络流,可是没有敲出来.各种反面样例推倒自己(究其原因是不愿意写暴力推断的).. 首先是简单的行列建边.源点向行建边.容量为该行元素和,汇点和列建边.容量为该列元素和.全部的行向全部的列建边,容量为K. 跑一次最大流.满流则有解,否则无解. 接下来是推断解是否唯一. 这个题解压根没看懂.还是暴力大法好. 最简单的思想就是枚举在一个矩形的四个端点.设A.D为主对角

【HDU】4918 Query on the subtree 点分治+树状数组

传送门:[HDU]4918 Query on the subtree 题目分析: 首先,简化问题. 1.求一次到点u的距离不超过d的点的个数.很容易,一次O(NlogN)的点分治便可以完成. 2.多次进行操作1.此时不能每次都O(NlogN)了,太慢了.我们考虑到对于点分治,树的重心一共有logN层,第一层为整棵树的重心,第二层为第一层重心的子树的重心,以此类推,每次至少分成两个大小差不多的子树,所以一共有logN层.而且,对于一个点,他最多只属于logN个子树,也就是最多只属于logN个重心.

【HDU】1754 I hate it ——线段树 单点更新 区间最值

I Hate It Time Limit: 9000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 37448    Accepted Submission(s): 14816 Problem Description 很多学校流行一种比较的习惯.老师们很喜欢询问,从某某到某某当中,分数最高的是多少.这让很多学生很反感. 不管你喜不喜欢,现在需要你做的是,就是按照老师的要

【HDU】 1160 FatMouse&#39;s Speed (DP)

一开始写的dfs进行记忆化结果不知道怎么进行路径的记录...改成循环就好了 dp[i] = max(dp[j]) + 1 , weight[j] < weight[j] && speed[j] > speed[i] 一开始进行一次排序使得重量递增,这样只需要考虑速度就好了 #include<cstdio> #include<algorithm> using namespace std; const int maxn = 10005; struct Mou

【hdu】Mayor&#39;s posters(线段树区间问题)

需要离散化处理,线段树的区间修改问题. 需要注意的就是离散化的时候,由于给的数字是一段单位长度,所以需要特殊处理(因为线段的覆盖和点的覆盖是不一样的) 比如:(1,10)(1,4) (6,10) 离散化之后是 1 , 4 , 6 , 10 分别离散为 1 2 3 4 覆盖的时候先覆盖1 4 之后覆盖了1 2 之后覆盖了 2 3,结果为2 但是实际上应该是3 13450359 201301052100 2528 Accepted 1140K 985MS C++ 1960B 2014-09-17 1

【HDU】4908 (杭电 BC #3 1002题)BestCoder Sequence ——哈希

BestCoder Sequence Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 573    Accepted Submission(s): 201 Problem Description Mr Potato is a coder.Mr Potato is the BestCoder. One night, an amazing s

【HDU】 2732 Leapin&#39; Lizards

Leapin' Lizards 题目链接 Leapin'Lizards 题目大意 给你两个图,一个用0,1,2,3表示,一个用 L 或 . 表示.其中用L表示的图中,有L的位置表示有蜥蜴,没有L的位置表示没有蜥蜴.用数字表示的图中,数字表示当前位置柱子的高度,每次一个蜥蜴可以从一个柱子跳到距离d以内的另外一个柱子,每跳跃一次,当前柱子的高度就减一,问最后会有多少只蜥蜴被困在里面. 题解 首先,可以明显的看到,一个柱子是有固定的通过次数的,这一点跟网络流中边的属性很像,但是这里的柱子是点,并不是边