1139B B.Chocolates

You went to the store, selling n types of chocolates. There are ai chocolates of type i in stock.

You have unlimited amount of cash (so you are not restricted by any prices) and want to buy as many chocolates as possible. However if you buy xi chocolates of type i (clearly, 0≤xi≤ai), then for all 1≤j<i at least one of the following must hold:

xj=0 (you bought zero chocolates of type j)
xj<xi (you bought less chocolates of type j than of type i)
For example, the array x=[0,0,1,2,10] satisfies the requirement above (assuming that all ai≥xi), while arrays x=[0,1,0], x=[5,5] and x=[3,2] don’t.

Calculate the maximum number of chocolates you can buy.

Input
The first line contains an integer n (1≤n≤2⋅105), denoting the number of types of chocolate.

The next line contains n integers ai (1≤ai≤109), denoting the number of chocolates of each type.

Output
Print the maximum number of chocolates you can buy.

input
5
1 2 1 3 6
output
10
input
5
3 2 5 4 10
output
20
input
4
1 1 1 1
output
1
Note
In the first example, it is optimal to buy: 0+0+1+3+6 chocolates.

In the second example, it is optimal to buy: 1+2+3+4+10 chocolates.

In the third example, it is optimal to buy: 0+0+0+1 chocolates.
题目大意: 有n种巧克力,每种ai个,从最后一种巧克力开始选,前一种的数目要小于后一种的数目,问最多能买到多少个巧克力。
思路: 用数组从后往前遍历,直到取下一个数目为0跳出循环结束。

#include <iostream>
#include <cstring> 
using namespace std;
int main() {
	int n, a[200005], maxn = 0;
	long long ans = 0;
	scanf("%d", &n);
	for(int i = 0; i < n; i++) {
		scanf("%d", &a[i]);
	}
	if(n == 1) printf("%d", a[0]); // 只有一种直接输出答案 
	else {
		ans = a[n-1]; // 最后一种的数目 
		for(int i = n-2; i >= 0; i--) { // 往前遍历 ,当前的数目只能比前一个取得数目更小 
			if(a[i] < a[i+1]) { // 小于时直接加 
				ans += a[i];
				if(a[i] == 1) break; // 当前已经为1,下一个定为0,结束 
			} 
			else { // 大于加前一个的数目减一 
				a[i] = a[i+1] - 1;
				if(a[i] == 0) break; // 前一个的数目为1,结束 
				ans += a[i];
			}
		}
		printf("%I64d\n", ans);	
	}
	return 0;
} 
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值