codeforces 484D Kindergarten (dp、贪心)

题意:给n个数,分成若干个连续组,每组获益为max-min,输出最大获益。

参考:http://blog.csdn.net/keshuai19940722/article/details/40873581

参考的链接里说得很明白了,我的dp[i][0]是升序,dp[i][1]是降序,习惯而已。

这题关键点就是,如果a[i-1]<a[i]>a[i+1],显然3个分开(a[i]归左或右)不比在一起差。

#include <cstdio>
#include <cstring>
#include <iostream>
#include <cmath>
#include <algorithm>
#include <vector>
#include <string>
#include <set>
#include <queue>
#include <map>
#include <ctime>
using namespace std;

#define ll long long
#define MP make_pair

#define inf 1e9
#define eps 1e-8

#define maxn 1010000

int a[maxn];
ll dp[maxn][2];
int main(){
	int n;
	while(~scanf("%d",&n)){
		for(int i=0;i<n;++i) scanf("%d",a+i);
		dp[0][0]=dp[0][1]=0;
		for(int i=1;i<n;++i){
			if(a[i-1]<a[i]){
				dp[i][0] = max(dp[i-1][0]+a[i]-a[i-1], dp[i-1][1]);
				dp[i][1] = max(dp[i-1][0], dp[i-1][1]);
			}else {
				dp[i][0] = max(dp[i-1][0], dp[i-1][1]);
				dp[i][1] = max(dp[i-1][1]+a[i-1]-a[i], dp[i-1][0]);
			}
		}
		printf("%I64d\n", max(dp[n-1][0], dp[n-1][1]));
	}
	return 0;
}
时间: 2024-10-10 14:28:48

codeforces 484D Kindergarten (dp、贪心)的相关文章

Codeforces 484D Kindergarten(dp)

题目链接:Codeforces 484D Kindergarten 题目大意:给定一个序列,可以分为若干段,每份的值即为该段中的最大值减掉最小值.问说所有段的总和最大为多少. 解题思路:dp[i][j],表示第i个位置,j为0时为升序状态,j为1是为降序状态.根据a[i]和a[i-1]的大小可以确定升降序的转 移.比如1 5 5 7,在第2个5的位置,即使出现了相等的情况,也会是分段的情况会更优:1 5 6 7 只有连续升序的状态 才需要考虑说是否成段. #include <cstdio> #

Codeforces 77C 树形dp + 贪心

题目链接:点击打开链接 题意: 给定n个点, 每个点的豆子数量 下面是一棵树 再给出起点 每走到一个点,就会把那个点的豆子吃掉一颗. 问:回到起点最多能吃掉多少颗豆子 思路:树形dp 对于当前节点u,先把子节点v都走一次. 然后再往返于(u,v) 之间,直到u点没有豆子或者v点没有豆子. dp[u] 表示u点的最大值.a[u] 是u点剩下的豆子数. #include <cstdio> #include <vector> #include <algorithm> #inc

Codeforces Round #276 (Div. 1)D.Kindergarten DP贪心

D. Kindergarten In a kindergarten, the children are being divided into groups. The teacher put the children in a line and associated each child with his or her integer charisma value. Each child should go to exactly one group. Each group should be a

484D - Kindergarten DP

把每一段单调序列分成一组可以接近最优质. 然后在此基础上讨论这一段的单调序列的两个端点该分到哪个序列里面,记录一下最优值. #include <algorithm> #include <iostream> #include <cstring> #include <cstdlib> #include <cstdio> #include <queue> #include <cmath> #include <stack&g

CodeForces 484D Kindergarten

题意: 将含有n(10^6)个元素的序列a划分成几段  每段为连续的一些元素  每段的价值为段中最大值减去最小值  总价值为所有段的价值和  求  最大的总价值 思路: 不难想到一个dp的转移方程 dp[i] = max( dp[j] + max(a[j+1]...a[i]) - min(a[j+1]...a[i]) )  但是dp是n^2的会TLE 注意观察转移方程  其中的max-min的部分很有特点  因为只关心这段区间的max和min  所以其他值都是没必要的  那么没有必要的值如果放在

Codeforces 459E Pashmak and Graph(dp+贪心)

题目链接:Codeforces 459E Pashmak and Graph 题目大意:给定一张有向图,每条边有它的权值,要求选定一条路线,保证所经过的边权值严格递增,输出最长路径. 解题思路:将边按照权值排序,每次将相同权值的边同时加入,维护每个点作为终止点的最大长度即可. #include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int maxn = 3

Codeforces 830A. Office Keys (背包dp+贪心) / (二分+贪心)

题目链接: http://codeforces.com/problemset/problem/830/A 题意: n个人,k个钥匙(n<=k),p表示这些人要到达的位置 给出n个人的位置以及钥匙的位置,问花时间最多的那个人用时最少是多少?? 思路: 二分+贪心: 二分最少时间,需要对a,b位置数组排序,我们check函数只需要从左到右一个一个找过去,因为如果选后边的点,可能会使结果更差,假如当前这个人选后面的点,那可能会选中后面的人可以选的唯一的钥匙,不会使解更优. check(40)的时候答案

codeforces219C - Color Stripe DP+贪心

题意:给你n,k,大意就是说给你一个已经涂满颜色长为n的字符串,现有k种颜色可以选择,问你最少要改变多少个箱子的颜色使得相邻箱子之间颜色不同. 解题思路:当k = 2 时单独讨论,不能用贪心,其余情况都可贪心得到. 解题代码: 1 // File Name: 219c.cpp 2 // Author: darkdream 3 // Created Time: 2014年07月26日 星期六 15时45分56秒 4 5 #include<vector> 6 #include<list>

ZOJ 2109 FatMouse&#39; Trade (背包 dp + 贪心)

链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=1109 FatMouse prepared M pounds of cat food, ready to trade with the cats guarding the warehouse containing his favorite food, JavaBean. The warehouse has N rooms. The i-th room contains J