codeforces 659G G. Fence Divercity(dp)

题目链接:

G. Fence Divercity

time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

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 thei-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.

Examples
input
2
1 1
output
0
input
3
3 4 2
output
13

题意

给你这样的一块东西(啊啊啊,不知道怎么说好),然后把它分成两块,当然两块肯定是在连续的,而且要求下面的一块每列至少为1,问有多少种切法;


思路:


dp[i]表示在第i列包含高为min(a[i],a[i+1])的那一块的切法,转移的方程详细看代码;
一开始dp[i]想表示前i列的答案,后来发现这样转移方程还得用回溯各种麻烦,想了一下午才想到这样表示,感觉智商不够啊啊啊;

AC代码:

/*
2014300227    659G - 28    GNU C++11    Accepted    234 ms    17820 KB
*/
#include <bits/stdc++.h>
using namespace std;
const int N=1e6+4;
const int mod=1e9+7;
typedef long long ll;
ll dp[N],a[N];
int n,x;
int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&x);
        //cin>>a[i];//我去,此处居然就是传说中的cin会tle
        a[i]=(ll)(x-1);
    }
    ll ans=0;
    a[0]=0;
    ans=a[1];
    dp[1]=min(a[1],a[2]);
    a[n+1]=a[n]+2;//dp[i]=包含min(a[i],a[i+1])的切法;
    for(int i=2;i<=n;i++)
    {
        dp[i]=min(a[i],a[i+1])+min(a[i-1],min(a[i],a[i+1]))*dp[i-1];
        dp[i]%=mod;
        if(a[i]<=a[i+1])
        {
            ans+=dp[i];
        }
        else
        {
            ans+=a[i]+min(a[i],a[i-1])*dp[i-1];
        }
        ans%=mod;
    }
    cout<<ans<<"\n";
    return 0;
}

 

 
posted @ 2016-04-01 17:59  LittlePointer  阅读(319)  评论(0编辑  收藏  举报