【POJ3666】【USACO 2008 Feb Gold】 2.Cow Game 动规

题意:有若干个数,然后可以花费i的代价让某个数+i或者-i。

现在要求让你把序列排成不升或者不降,问最小代价。

题解:

首先可以证明,最优花费下最后所有的数都可以是现在的某个数:

证:如果两个数调整后在两个数中间,那么可以把两个数都变为其中一个数,而代价显然是等同的。

这个出来后就好做了。

我们可以先离散化一下,然后f[i][j]表示第i个数变为j时1~i这些数保持非严格单调的最小花费

转移时f[i][j]不必n*n枚举,可以维护一个前缀最优(非常水),然后O(1)转移。

然后做一遍非升,一遍非降出解。

代码:

#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define N 2500
#define inf 0x3f3f3f3f3f3f3f3fll
using namespace std;
struct LSH
{
	int x,id;
	bool operator < (const LSH &a)const{return x<a.x;}
}lsh[N];
int cnt,n,w[N];
long long f[N][N];
int main()
{
//	freopen("test.in","r",stdin);
	int i,j,k;
	scanf("%d",&n);
	for(i=1;i<=n;i++)scanf("%d",&lsh[i].x),lsh[i].id=i;
	sort(lsh+1,lsh+n+1),lsh[0].x=-1;
	for(i=1;i<=n;i++)
	{
		if(lsh[i].x!=lsh[i-1].x)lsh[++cnt].x=lsh[i].x;
		w[lsh[i].id]=cnt;
	}
	// 离散化结束,lsh中对应原值

//升序
	for(i=1;i<=n;i++)
	{
		long long temp=inf;
		for(j=0;j<=cnt;j++)
		{
			temp=min(temp,f[i-1][j]);
			f[i][j]=temp+abs(lsh[w[i]].x-lsh[j].x);
		}
	}
	long long ans1=inf;
	for(i=0;i<=cnt;i++)ans1=min(ans1,f[n][i]);
//降序
	for(i=1;i<=n;i++)
	{
		long long temp=inf;
		for(j=cnt;j>=0;j--)
		{
			temp=min(temp,f[i-1][j]);
			f[i][j]=temp+abs(lsh[w[i]].x-lsh[j].x);
		}
	}
	long long ans2=inf;
	for(i=0;i<=cnt;i++)ans2=min(ans2,f[n][i]);
	cout<<min(ans1,ans2)<<endl;
	return 0;
}

复制去Google翻译翻译结果

时间: 2024-12-25 04:57:27

【POJ3666】【USACO 2008 Feb Gold】 2.Cow Game 动规的相关文章

USACO 2008 FEB Eating Together

题目描述 The cows are so very silly about their dinner partners. They have organized themselves into three groups (conveniently numbered 1, 2, and 3) that insist upon dining together. The trouble starts when they line up at the barn to enter the feeding

【USACO 2008 Open Gold】 3.Cow Neighborhoods 平衡树、并查集

题解: 首先曼哈顿距离有些不好维护,但是它可以转化: 一个点本来的坐标是(x,y),那么可以转化成(x+y,x-y) 这样就人为构造出一种性质:1.2两点曼哈顿距离=max(|x1-x2|,|y1-y2|); 这样我们就可以排序单调搞掉一维,然后另一维只需要求前驱后继到该点的距离 满足则加并查集. 这个过程可以用权值线段树,也可以用平衡树.但是权值线段树还需要离散化,反而代码多了. 代码: #include <cmath> #include <cstdio> #include &l

【BZOJ1229】【USACO 2008 Nov Gold】 4.Toys sadstory 三分+贪心

sad story:我们自己oj的数据貌似有点问题.标程WA了5% 题解: 复制去Google翻译翻译结果 首先引一下VFK神犇的证明来证明一下这道题是三分.. { 我来告诉你世界的真相 = = 因为这题能最小费用最大流 每次最短路长度不降 所以是单峰的 最短路长度就是差分值.. 所以一阶导不降.. 是不是简单粗暴 你要证函数是单峰的. 当然是证斜率什么的 } 三分完初始买了多少个玩具,然后就是贪心. 首先我想说这个贪心真动规.虽然它真的是贪心. 首先先说一种错误的贪心. 就是从前往后扫,优先用

[USACO 2009 Feb Gold] Fair Shuttle (贪心+优先队列)

题目大意:有N个站点的轻轨站,有一个容量为C的列车起点在1号站点,终点在N号站点,有K组牛群,每组数量为Mi(1≤Mi≤N),行程起点和终点分别为Si和Ei(1≤Si<Ei≤N).计算最多有多少头牛可以搭乘轻轨. 一道经典的贪心题目,每当一头牛上车的时候,如果超载,我们就优先踢出去行程终点比较远的那部分牛 而 踢出哪些行程终点较远的牛 以及 哪些在车上的牛在这站到达了终点,都可以用优先队列来维护,复杂度约为 贴上代码: 1 #include <cstdio> 2 #include <

【POJ3659】【USACO 2008 Jan Gold】 3.Cell Phone Network 树上最小支配集/贪心 两种做法

题意:求树上最小支配集 最小支配集:点集,即每个点可以"支配"到相邻点,求最少点数可以使所有点被支配. 图上的最小支配集是NP的,但是树上的可以DP做,是O(n)的. 暴力做就好了, f[i]表示此 点被选时的子树全支配的最小代价 g[i]表示其父亲节 点被选时的子树全支配的最小代价 h[i]表示其某子节 点被选时的子树全支配的最小代价 然后暴力转移. (v是子节点) f[x]=∑(min(f[v],min(g[v],h[v])))+1; g[x]=∑(min(f[v],h[v]));

USACO 2017 FEB Gold visitfj 最短路

题意 有一幅n*n的方格图,n <= 100,每个点上有一个值.从(1,1)出发,走到(n,n),只能走四联通.每走一步花费t,每走三步需要花费走完三步后到达格子的值.求最小花费的值. 拆点,dis[i][j]表示到达第i个点时走的总步数模3等于j时的最小花费值. #include <cstdio> #include <cstdlib> #include <cstring> #include <string> #include <algorith

【BZOJ1589】【USACO 2008 Dec Gold】 1.Trick or Treat on the Farm 基环树裸DP、

没测样例一遍A这真是-- 题意:每个点都有且仅有一个出边(可以出现自环),然后这样一个点出发就会走过且一定走过某些点. 问每个点出发都会走过几个点. 首先这是基环树无疑. 然后就是裸DP了. 这个的关键就是找环,仅此. #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #define N 101000 using namespace std; int n

【POJ3657】【USACO 2008 Jan Gold】 1.Haybale Guessing 二分答案,并查集check

题意: 输入n.m表示数列长度为n,有m条有序的限制{l,r,x}. 限制:l~r间所有数最小值为x. 问到第几条限制开始出现矛盾,都不出现输出"0". 题解: 首先这题比较厉害,正常解有点难,不妨转化成二分答案. 我们二分"答案",也就是第ans条出现矛盾. 考虑到若一条限制S所在区间被另一个限制Seg包含,且Seg这条限制的x又比S.x大, 那么也就是意为 ① [Seg.l,Seg.r]间最小值为Seg.x ② [S  .l,S  .r]间最小值为S  .x ③

【POJ3658】【USACO 2008 Jan Gold】 2.Artificial Lake人工湖 单调栈

人工湖 Time Limit: 1 Sec  Memory Limit: 128 MB Description 夏日那让人喘不过气的酷热将奶牛们的烦躁情绪推到了最高点.最终,FJ 决定建一个人工湖供奶牛消暑之用.为了使湖看起来更加真实,FJ决定将湖的 横截面建成N(1 <= N <= 100,000)个连续的平台高低错落的组合状,所有的平台 从左到右按1..N依次编号.当然咯,在湖中注入水后,这些平台都将被淹没. 平台i在设计图上用它的宽度W_i(1 <= W_i <= 1,000