D. Riverside Curio
D. Riverside Curio
? https://codeforces.com/problemset/problem/957/D
Arkady decides to observe a river for n consecutive days. The river’s water level on each day is equal to some real value.
Arkady goes to the riverside each day and makes a mark on the side of the channel at the height of the water level, but if it coincides with a mark made before, no new mark is created. The water does not wash the marks away. Arkady writes down the number of marks strictly above the water level each day, on the i-th day this value is equal to mi.**
Define di as the number of marks strictly under the water level on the i-th day. You are to find out the minimum possible sum of di over all days. There are no marks on the channel before the first day.
Input
The first line contains a single positive integer n (1?≤?n?≤?105) — the number of days.
The second line contains n space-separated integers m1,?m2,?…,?mn (0?≤?mi?<?i) — the number of marks strictly above the water on each day.
Output
Output one single integer — the minimum possible sum of the number of marks strictly below the water level among all days.
Examples
input
6 0 1 0 3 0 2output
6input
5 0 1 2 1 2output
1input
5 0 1 1 2 2output
0Note
In the first example, the following figure shows an optimal case.
Note that on day 3, a new mark should be created because if not, there cannot be 3 marks above water on day 4. The total number of marks underwater is 0?+?0?+?2?+?0?+?3?+?1?=?6.
In the second example, the following figure shows an optimal case.
題意:
一個(gè)人每天去河邊看水位,水的高度與之前不同就在這個(gè)高度做標(biāo)記,如果這個(gè)高度已經(jīng)標(biāo)記過(guò)了就不做任何事,數(shù)組m有n個(gè)元素,m 1代表第一天來(lái)的時(shí)候,看到的水面上的標(biāo)記,一定是0(因?yàn)榈谝惶觳砰_(kāi)始標(biāo)記),m 2代表第二天看到的水面上的標(biāo)記(因?yàn)樗粫?huì)變),以此類推。求所有天中嚴(yán)格低于水位的標(biāo)記數(shù)目的最小和
分析:
難點(diǎn)主要是推式子,我們只要知道每天總共有多少個(gè)標(biāo)記,和每天在水面上的標(biāo)記數(shù),相減再-1(減去剛好貼著水面的標(biāo)記)就是在水面下的標(biāo)記了,最后求和就是答案了。
設(shè)t[i]為第i天的劃線數(shù)量,第一天為1,m[i]為第i天嚴(yán)格在上面的數(shù),b[i]為第i天嚴(yán)格在下面的數(shù),那么有
b[i]=t[i]?m[i]?1b[i] = t[i]-m[i]-1 b[i]=t[i]?m[i]?1
現(xiàn)在問(wèn)題就是求b數(shù)組,也就是求在水面下的標(biāo)記數(shù)(這里絕對(duì)是個(gè)難點(diǎn))。
由一個(gè)例子,Day 1時(shí)m 1是0,此時(shí)標(biāo)記數(shù)就是0+1=1(因?yàn)楫?dāng)天標(biāo)記的是貼著水面的,所以要加一),Day 2時(shí)m 2是1,此時(shí)標(biāo)記數(shù)就是1+1=2,但是到了Day 3,m 3就變成了0,因?yàn)檫@是水位突然猛漲,人家已經(jīng)看不到之前的標(biāo)記了,既然變成0了,那不就不知道第三天究竟有幾個(gè)標(biāo)記了嗎?
確實(shí)不知道,但我們知道的是,此時(shí)的標(biāo)記數(shù)不是2個(gè)就是3個(gè)。為什么?因?yàn)榇藭r(shí)看不到標(biāo)記,水位要么回到了之前的高度(標(biāo)記貼著水面),要么高于之前的標(biāo)記。我們要確定是2還是3,就得看后面。因?yàn)镈ay 4時(shí)看到了3個(gè)標(biāo)記,所以Day 3的時(shí)候只能是3個(gè)標(biāo)記,也就是說(shuō),水位上升的時(shí)候要看后面才能確定標(biāo)記數(shù)。
先正向遍歷一遍,水位下降時(shí)(m增大),我們可以確定有幾個(gè)標(biāo)記(m+1),水位上升到要標(biāo)記新的標(biāo)記時(shí),就取昨天的標(biāo)記數(shù)。合并到一起就是:
for(int i=1;i<=n;++i) t[i]=max(t[i-1],m[i]+1);為了求水位上升時(shí)的標(biāo)記數(shù),需要再反向遍歷一遍。
for(int i=n-1;i>=1;--i)if(t[i+1]-t[i]>1)t[i]=t[i+1]-1;注意,這里判斷相鄰兩天標(biāo)記數(shù)之差不能超過(guò)1,為什么?因?yàn)槟忝看蝸?lái)河邊標(biāo)記,要么不標(biāo)記,要么就標(biāo)記一次呀,所以兩邊最多只能相差1,且左邊等于右邊減1。為什么不是右邊等于左邊加1?前面已經(jīng)說(shuō)了,比如第三天的標(biāo)記數(shù)不是2個(gè)就是3個(gè),我們?nèi)×说诙斓臉?biāo)記數(shù)(2),所以要讓標(biāo)記數(shù)盡量大,讓左邊大一點(diǎn),而不是讓右邊小一點(diǎn)。
代碼:
#include<iostream> #include<algorithm> #define int long long #define Please return #define AC 0 using namespace std; const int N=1e6+1; void fastio(){ios::sync_with_stdio(false);cin.tie(0),cout.tie(0);} int a[N]; int t[N]; signed main() {fastio();int n,ans=0;cin>>n;for(int i=1;i<=n;++i)cin>>a[i];for(int i=1;i<=n;++i) t[i]=max(t[i-1],a[i]+1);for(int i=n-1;i>=1;--i)if(t[i+1]-t[i]>1)t[i]=t[i+1]-1;for(int i=1;i<=n;++i)ans+=t[i]-a[i]-1;cout<<ans<<endl;Please AC; }總結(jié)
以上是生活随笔為你收集整理的D. Riverside Curio的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: WikiTaxi_Importer_1.
- 下一篇: 激光检测----激光原理简述