CodeForces - 659G Fence Divercity (DP)好题

106 篇文章 0 订阅
85 篇文章 0 订阅
CodeForces - 659G
Time Limit: 2000MS Memory Limit: 262144KB 64bit IO Format: %I64d & %I64u

 Status

Description

Long ago, Vasily built a good fence at his country house. Vasily calls a fence good, if it is a series of n consecutively fastened vertical boards of centimeter width, the height of each in centimeters is a positive integer. The house owner remembers that the height of the i-th board to the left is hi.

Today Vasily decided to change the design of the fence he had built, by cutting his top connected part so that the fence remained good. The cut part should consist of only the upper parts of the boards, while the adjacent parts must be interconnected (share a non-zero length before cutting out of the fence).

You, as Vasily's curious neighbor, will count the number of possible ways to cut exactly one part as is described above. Two ways to cut a part are called distinct, if for the remaining fences there is such i, that the height of the i-th boards vary.

As Vasily's fence can be very high and long, get the remainder after dividing the required number of ways by 1 000 000 007(109 + 7).

Input

The first line contains integer n (1 ≤ n ≤ 1 000 000) — the number of boards in Vasily's fence.

The second line contains n space-separated numbers h1, h2, ..., hn (1 ≤ hi ≤ 109), where hi equals the height of the i-th board to the left.

Output

Print the remainder after dividing r by 1 000 000 007, where r is the number of ways to cut exactly one connected part so that the part consisted of the upper parts of the boards and the remaining fence was good.

Sample Input

Input
2
1 1
Output
0
Input
3
3 4 2
Output
13

Hint

From the fence from the first example it is impossible to cut exactly one piece so as the remaining fence was good.

All the possible variants of the resulting fence from the second sample look as follows (the grey shows the cut out part):

Source

//题意:
现在有n堵紧贴着的墙(墙是由砖块累成的),每堵墙都有一个高度,现在想将这n堵墙拆掉,并且拆墙有一定的规则,
1、每堵墙都不能把最下面的那块砖拆掉;
2、拆的砖头必须是连着的。
问一共有几种拆法?
//思路:
dp[i][0]存放前i列的所有的情况数;
dp[i][1]存放的是前i列全连通的情况数+第i+1列的情况数。
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<map>
#include<queue>
#include<stack>
#include<algorithm>
#include<iostream>
#define INF 0x3f3f3f3f
#define ull unsigned long long
#define ll long long
#define IN __int64
#define N 1000010
#define M 1000000007
using namespace std;
ll h[N],dp[N][2];
int n;
int main()
{
	int i,j;
	while(scanf("%d",&n)!=EOF)
	{
		for(i=1;i<=n;i++)
			scanf("%lld",&h[i]),h[i]--;
		for(i=1;i<=n;i++)
		{
			dp[i][0]=(dp[i-1][0]+dp[i-1][1]*min(h[i],h[i-1])+h[i])%M;
			dp[i][1]=(min(h[i+1],h[i])+min(min(h[i],h[i-1]),h[i+1])*dp[i-1][1])%M;
		}
		printf("%d\n",dp[n][0]);
	}
	return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值