比赛 20110412 评测结果 AAAAAAAAAW
题目名称 山顶问题 最终得分 90
用户昵称 苏轼 运行时间 0.000 s
代码语言 C++ 内存使用 0.00 MiB
提交时间 2011-04-12 10:21:40
显示代码纯文本
#include <cstdio>
#include <vector>
using namespace std;
const int MAXN=100005;
const int oo=~0u>>2;

struct Node
{
	int w,l,r;
	Node(int _w,int _l,int _r):
		w(_w),l(_l),r(_r){}
};
int tot;
vector<Node> v;

void push_heap(const Node &a)
{
	v.push_back(a);
	tot++;
}

int N,K;
int H[MAXN];

int getsum(int l,int r)
{
	int to=max(H[l],H[r]);
	int ans=0;
	for(int i=l;i<=r;i++)
		if (H[i]>to)
			ans+=H[i]-to;
	return ans;
}

int pop_heap()
{
	int minw=oo,ri;
	for(int i=0;i<tot;i++)
		if (v[i].w<minw)
			minw=v[i].w,ri=i;
	int to=max(H[v[ri].l],H[v[ri].r]);
	for(int i=v[ri].l;i<=v[ri].r;i++)
		if (H[i]>to)
			H[i]=to;
	if (H[v[ri].l]>=H[v[ri].r])
	{
		v[ri-1].r=v[ri].r;
		v[ri-1].w=getsum(v[ri-1].l,v[ri-1].r);
	}
	else
	{
		v[ri+1].l=v[ri].l;
		v[ri+1].w=getsum(v[ri+1].l,v[ri+1].r);
	}
	v.erase(v.begin()+ri);
	tot--;
	return minw;
}

int main()
{
	freopen("peaks.in","r",stdin);
	freopen("peaks.out","w",stdout);
	scanf("%d%d",&N,&K);
	for(int i=1;i<=N;i++)
		scanf("%d",H+i);
	H[0]=0;
	H[++N]=0;
	for(int i=1,j=0,l=0;i<=N;i++)
	{
		if (H[i]!=H[i-1])
		{
			if (j==0)
			{
				if (H[i]<H[i-1])
					j=1;
			}
			else
			{
				if (H[i]>H[i-1])
				{
					push_heap(Node(getsum(l,i-1),l,i-1));
					j=0;l=i-1;
				}
			}
		}
		if (i==N)
			push_heap(Node(getsum(l,N),l,N));
	}
	int re=0;
	while(tot>K)
		re+=pop_heap();
	printf("%d\n",re);
	return 0;
}