您的位置:首页 > Web前端

codeforces 659G G. Fence Divercity(dp)

2016-04-01 17:59 357 查看
题目链接:

G.FenceDivercity

timelimitpertest
2seconds

memorylimitpertest
256megabytes

input
standardinput

output
standardoutput

Longago,Vasilybuiltagoodfenceathiscountryhouse.Vasilycallsafencegood,ifitisaseriesofnconsecutivelyfastenedverticalboardsofcentimeterwidth,theheightofeachincentimetersisapositiveinteger.Thehouseownerremembersthattheheightofthei-thboardtotheleftishi.

TodayVasilydecidedtochangethedesignofthefencehehadbuilt,bycuttinghistopconnectedpartsothatthefenceremainedgood.Thecutpartshouldconsistofonlytheupperpartsoftheboards,whiletheadjacentpartsmustbeinterconnected(shareanon-zerolengthbeforecuttingoutofthefence).

You,asVasily'scuriousneighbor,willcountthenumberofpossiblewaystocutexactlyonepartasisdescribedabove.Twowaystocutapartarecalleddistinct,iffortheremainingfencesthereissuchi,thattheheightofthei-thboardsvary.

AsVasily'sfencecanbeveryhighandlong,gettheremainderafterdividingtherequirednumberofwaysby1 000 000 007(109 + 7).

Input
Thefirstlinecontainsintegern(1 ≤ n ≤ 1 000 000)—thenumberofboardsinVasily'sfence.

Thesecondlinecontainsnspace-separatednumbersh1, h2, ..., hn(1 ≤ hi ≤ 109),wherehiequalstheheightofthei-thboardtotheleft.

Output
Printtheremainderafterdividingrby1 000 000 007,whereristhenumberofwaystocutexactlyoneconnectedpartsothatthepartconsistedoftheupperpartsoftheboardsandtheremainingfencewasgood.

Examples

input
2
11


output
0


input
3
342


output
13

题意:

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


思路:

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

AC代码:


/*
2014300227659G-28GNUC++11Accepted234ms17820KB
*/
#include<bits/stdc++.h>
usingnamespacestd;
constintN=1e6+4;
constintmod=1e9+7;
typedeflonglongll;
lldp
,a
;
intn,x;
intmain()
{
scanf("%d",&n);
for(inti=1;i<=n;i++)
{
scanf("%d",&x);
//cin>>a[i];//我去,此处居然就是传说中的cin会tle
a[i]=(ll)(x-1);
}
llans=0;
a[0]=0;
ans=a[1];
dp[1]=min(a[1],a[2]);
a[n+1]=a
+2;//dp[i]=包含min(a[i],a[i+1])的切法;
for(inti=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";
return0;
}





                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: