修路
返回題目
由於雨水沖刷,長度為N的路面下陷。勤勞的養路工人使用機器恢復路面,機器每天只能對一段路面[L,R]之間的區域進行1個單位深度的填充修補,道路的
路況用下陷的深度表示。請程式設計輸出修好這條路至少需要的天數。
【輸入形式】
第一行一個整數N;
第二行N個空格隔開的整數,表示路面的下陷程度。
【輸出形式】
一個整數,表示所用的天數。
【樣例輸入】
6
1 3 2 4 5 3
【樣例輸出】
6
【樣例說明】
6天修補[1,6], [2,6], [2,2], [4,6], [4,5], [5,5]路段即可。
【評分標準】
0<N<100000;
輸出正確的答案。
1
它就是一個貪心。
題目裡給的樣例是4,3,2,5,3,5;
可以選擇一個區間進行“填坑”操作;
所以我們的貪心策略是:
若a[i]>a[i-1],計數器sum+=a[i]-a[i-1];
那麼為什麼這樣貪心是對的呢?
貪心證明
假設現在有一個坑,但旁邊又有一個坑。
你肯定會選擇把兩個同時減1;
那麼小的坑肯定會被大的坑“帶著”填掉。
大的坑也會減少a[i]-a[i-1]的深度,可以說是“免費的”;
所以這樣貪心是對的;
程式碼
#include<bits/stdc++.h>
using namespace std;
int n,a[100005];
long long ans=0;
int main()
{
cin>>n;
for(int i=1;i<=n;i++) cin>>a[i];
for(int i=2;i<=n;i++) if(a[i]>a[i-1]) ans+=a[i]-a[i-1];
cout<<ans+a[1];
return 0;
}
記得要加上a[1],或者在前面填一個0; (這是本蒟蒻第一次寫題解,支援一下哦。)
2
#include <cstdio>
#include <algorithm>
using namespace std;
int a[100010];
int main()
{
int n;
scanf("%d",&n);
int minn=0x3f3f3f3f;
for(int i=1;i<=n;++i)
{
scanf("%d",&a[i]);
if(a[i]<minn)minn=a[i];
}
for(int i=1;i<=n;++i)
a[i]-=minn;
long long sum=minn;
int k=0;
for(int i=1;;++i)//未知次操作
{
if(!a[k])
{
k++;
if(k==n+1)break;
}//遍歷非0段
int minx=a[k];
for(int j=k;j<=n;++j)
{
if(!a[j])break;
if(a[j]<minx)minx=a[j];
}
for(int j=k;j<=n;++j)
{
if(!a[j])break;
a[j]-=minx;
}//處理
sum+=minx;
}
printf("%lld\n",sum);
return 0;
}