Monkey Party(动态规划-区间dp-四边形不等式优化)

Monkey Party(动态规划-区间dp-四边形不等式优化)

judge:HDUOJ 3506
Time Limit: 4000/2000 MS (Java/Others)
Memory Limit: 131072/65536 K (Java/Others)
source:2010 ACM-ICPC Multi-University Training Contest(7)——Host by HIT

Problem Description

Far away from our world, there is a banana forest. And many lovely monkeys live there. One day, SDH(Song Da Hou), who is the king of banana forest, decides to hold a big party to
HDUOJ 3506

Input

HDUOJ 3506

Output

HDUOJ 3506

Sample Input

8
5 2 4 7 6 1 3 9

Sample Output

105

题意

n个猴子围成一个圈,每个猴子都需要交朋友。当一个猴子和别的猴子交朋友时这个猴子认识的猴子也会认识了这个新猴子,不过消耗的时间则是这些猴子所有的自我介绍的时间的总和。而我们要做的就是把那些自我介绍时间长的猴子尽可能少介绍,以达到总时间最少的目的

还有一个要注意的点是猴子是围成一个圈的,所以把数组往后复制一份来模拟一个圈。

四边形不等式优化具体怎么证明我也不太会,先贴在这,以后有机会再研究。

代码
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cstdio>
#define _for(i, a) for(int i = 0; i < (a); i++)
#define _rep(i, a, b) for(int i = (a); i <= (b); i++)
typedef long long ll;
const int maxn = 2005;
const int inf = 0x3f3f3f3f;
using namespace std;
int dp[maxn][maxn];
int a[maxn];
int s[maxn][maxn];
int n;
int main() {
	//freopen("in.txt", "r", stdin);
	while (cin >> n) {
		memset(dp, 0x3f, sizeof(dp));
		memset(a, 0, sizeof(a));
		_rep(i, 1, n) {
			cin >> a[i];
			a[i + n] = a[i];
		}
		n *= 2;
		_rep(i, 1, n) a[i] += a[i - 1], dp[i][i] = 0, s[i][i] = i;
		_rep(d, 2, n / 2) {
			for (int i = 1, j = i + d - 1; j <= n; i++, j++) {
				_rep(k, s[i][j - 1], s[i + 1][j]) {
					if (dp[i][j] > dp[i][k] + dp[k + 1][j] + a[j] - a[i - 1]) {
						dp[i][j] = dp[i][k] + dp[k + 1][j] + a[j] - a[i - 1];
						s[i][j] = k;
					}
				}
			}
		}
		n /= 2;
		int ans = inf;
		_rep(i, 1, n) {
			ans = min(ans, dp[i][i + n - 1]);
		}
		printf("%d\n", ans);
	}
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值