Loading

【题解】 P6364 1024 程序员节发橙子

蒟蒻题解第2篇

先分析下题意:

  • 输入一个数列。
  • 根据数列中元素的值按要求分配物品。
  • 求分配物品数量总和的最小值。

要求:

\(|x|\) 表示数列中第 \(x\) 个元素的值,\(-x-\) 表示第 \(x\) 个元素应分配的物品数量。

  • \(|x+1|>|x|\),则分配方案需满足 \(-x+1->-x-\)

  • \(|x+1|=|x|\),则分配方案需满足 \(-x+1-=-x-\)

  • \(|x-1|>|x|\),则分配方案需满足 \(-x-1->-x-\)

  • \(|x-1|=|x|\),则分配方案需满足 \(-x-1-=-x-\)

再思考波算法:

仔细思考下题意分析,你会发现这道题可以简化为在数列里跑两遍不降子序列(序列里分配物品数量+1),正着跑一遍,反着跑一遍,就可以满足临近两个同学的要求了。

最后实现代码:

154ms,8.25MB

#include<bits/stdc++.h>
#define maxn 1000010
#define ull unsigned long long
using namespace std;

int a[maxn],orange[maxn],n;
ull answer;//不开unsigned long long 会部分WA

int main()
{
	memset(a,0,sizeof(a));
	memset(orange,0,sizeof(orange));
	scanf("%d",&n);
	for(int i=1;i<=n;i++)
		scanf("%d",&a[i]);
	for(int i=2;i<=n;i++)//正着跑不降子序列
	{
		if(a[i-1]<a[i])
			orange[i]=orange[i-1]+1;
		if(a[i-1]==a[i])
			orange[i]=orange[i-1];
	}
	for(int i=n;i>=2;i--)//倒着跑不降子序列
	{
		if(a[i]<a[i-1])
			orange[i-1]=max(orange[i-1],orange[i]+1);
		if(a[i-1]==a[i])
			orange[i-1]=orange[i];
	}
	answer=n;//因为每个人至少要分1个橙子 所以答案初值为n
	for(int i=1;i<=n;i++)
		answer+=orange[i];
	printf("%lld",answer);
	return 0;
}
posted @ 2020-10-18 09:41    阅读(182)  评论(1编辑  收藏  举报