链接:戳这里
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.
Examples
input
2
1 1
output
0
input
3
3 4 2
output
13
Note
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):
题意:给出n块高度为hi的隔板组成的篱笆,要求削掉一个连通块(可以使一个格子也可以是多个)使得篱笆good,篱笆good的条件就是削掉后每个高度不为0,且不会被掏空,问有多少种削法
思路:我感觉画图更好理解吧,dp[i][j]表示当前的第i块隔板当做最后一块隔板的第j个格子的数量(当前的j做为要削的连通块的最右最下位置),当前隔板的高度为h[i](1<=j<=h[i])
分情况考虑:
1:h[i-1]<h[i]
那么 (h[i-1]+1<=j<=h[i]) 的dp[i][j]=1,这个应该很好理解吧
(1<=j<=h[i-1])的位置的数量则为{ sigma(dp[i-1][j]) }+1 最后+1是表示当前的j格子本身作为一个连通块
2:h[i-1]>=h[i]
这样的话dp[i][j] (1<=j<=h[i]) 则为{ sigma(dp[i-1][j]) }+1 简单画图就可以知道了
但是这样设的状态肯定会T啊,所以我们可以采取递推的形似来模拟dp的过程,每个dp[i][]都只和前一项dp[i-1][]有关
所以我们在递推的时候存在具体的数据就可以了,然后维护下输出值,具体看代码吧
代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<string>
#include<vector>
#include <ctime>
#include<queue>
#include<set>
#include<map>
#include<stack>
#include<iomanip>
#include<cmath>
#define mst(ss,b) memset((ss),(b),sizeof(ss))
#define maxn 0x3f3f3f3f
#define MAX 1000100
///#pragma comment(linker, "/STACK:102400000,102400000")
typedef long long ll;
typedef unsigned long long ull;
#define INF (1ll<<60)-1
#define mod 1000000007
using namespace std;
ll h[1000100];
int n;
int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++) scanf("%I64d",&h[i]),h[i]--;
ll last=0,val=0,ans=0,x=0;
for(int i=1;i<=n;i++){
ans=(ans+h[i])%mod;
if(h[i]>=h[i-1]){
val=(h[i-1]-last+x*last%mod)%mod;
ans=(ans+val*h[i-1]%mod)%mod;
last=h[i-1];
x=val+1;
} else{
if(h[i]>last) val=(h[i]-last+last*x%mod)%mod;
else val=h[i]*x%mod;
ans=(ans+val*h[i]%mod)%mod;
last=h[i];
x=val+1;
}
}
printf("%I64d\n",ans%mod);
return 0;
}