2620 序列问题 (序列合并问题——两两相邻)

2620 序列问题

对于一个给定的序列a1,a2...ana1,a2...an,我们对它进行一个操作Reduce(i)Reduce(i),

该操作将数列中的元素aiai和ai+1ai+1用一个元素max(aiai,ai+1ai+1)替代,这样得到一

个比原来序列短的新序列。这一操作的代价是max(aiai,ai+1ai+1)。进行n-1次该操作后,

可以得到一个长度为1的序列。我们的任务是计算代价最小的Reduce操作顺序,将给定

的序列变成长度为1的序列。

例如a序列为:1,2,3

那么最优的Reduce顺序为:

首先1,2合并花费为2,序列变为2,3

2,3合并,花费为3,序列变为3,长度为1。

所以答案为5。

输入

第1行:一个整数n表示给定序列的长度。(1 <= n <= 1,000,000 )
第2到n+1行:每行一个整数a[i]表示序列中的元素。(0 <=a[i]<= 1, 000, 000, 000)

输出

输出一个整数表示将序列通过Reduce操作变成一个元素的最小代价。

输入样例

3
1
2
3

输出样例

5

思路:

       19寒假好像做过一个类似的题,没啥印象了.

       这题直接考虑了单调性,然后单调栈更新答案,实际上

进一步考虑,只要相邻两个元素(n-1个数对)选大者加入答

案即可。

代码实现:

#include<iostream>
#include<string.h>
#include<math.h>
#include<set>
#include<queue>
#include<stdio.h>
#include<algorithm>
#define LL long long
#define INF 0x3f3f3f3f
#define ull unsigned long long
/*#ifdef MYHOME
  freopen("input.txt", "r", stdin);
#endif*/
using namespace std;

const int N = 4e5 + 100;
const int M = 4e5 + 100;

int arr[N];
int main() {
#ifdef MYHOME
  freopen("input.txt", "r", stdin);
#endif
	int n;
	long long ans;
	while (cin >> n) {
		ans = 0;
		for (int i = 1; i <= n; i++) {
			cin >> arr[i];
		}
		for (int i = 1; i < n; i++) {
			ans += max(arr[i], arr[i + 1]);
		}
		cout << ans << endl;
	}
	return 0;

}

单调栈代码:

#include<iostream>
#include<string.h>
#include<math.h>
#include<set>
#include<queue>
#include<stdio.h>
#include<algorithm>
#define LL long long
#define INF 0x3f3f3f3f
#define ull unsigned long long
/*#ifdef MYHOME
  freopen("input.txt", "r", stdin);
#endif*/
using namespace std;

const int N = 4e5 + 100;
const int M = 4e5 + 100;


int arr[N], sc[N],top;
int main() {
#ifdef MYHOME
  freopen("input.txt", "r", stdin);
#endif
  int n,tmpx,tmpy;
  long long ans;
  while (cin >> n) {
    top = ans = 0;
    for (int i = 1; i <= n; i++) {
      cin >> arr[i];
    }
    for (int i = 1; i <= n; i++) {
      if (top && arr[i] >= arr[sc[top]]) top--, ans += arr[i];
      sc[++top] = i;
    }
    top-- ;
    while (top > 0) {
      ans += arr[sc[top--]];
    }
    cout << ans << endl;
  }
  return 0;

}

THE END;

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值