通过题目可以知道要定若干个矩阵,使这个不规则图形充满。
不难想到,为了使矩阵尽量小,每一个矩阵的高应该要正好顶到h[i]。
如:
00000
10010
11011
11111
第一个矩阵应该高四个,因为如果还要加,还要在上面再加矩阵,显然并非最优。
同过以上思想,可以做一个大循环从1到n,则可以进行以下操作:
1.若h[i]=h[i-1],显然答案不会改变,因此不会有变化
2.若h[i]>h[i-1],我们可以进行一下思考:
01
11
11
新的高度肯定不可能被矩阵温泉覆盖,因此,我们可将答案+1.
3.若h[i]<h[i-1]。
00
10
11
第一次想,会觉得答案直接+1,如上图
但,见下图:
010
111
111
第一次的矩阵的矩阵已经覆盖过了,但又能想到,如果前面已经有了,是不是就不用覆盖了呢?
上面的思路大致无误,但:
01010
11011
11111
第一次高度虽然与最后相同,但由于中间有一个高度过低,让矩阵无法过来覆盖。
通过以上,不难想出用一个二维数组构建。
bool s[N][H]//第n个里面有几个高度过去有几个高度已经有了(打标记)
#include<bits/stdc++.h>
using namespace std;
const int N=100005,H=105;
int h[N];
bool s[N][H];
signed main(){
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
int n,ans=1;
cin>>n>>h[1];
s[1][h[1]]=true;
for(int i=2;i<=n;i++){
cin>>h[i];
if(h[i]==h[i-1]){
for(int j=1;j<=100;j++){
s[i][j]=s[i-1][j];
}
}
else if(h[i]>h[i-1]){
for(int j=1;j<=100;j++){
s[i][j]=s[i-1][j];
}
ans++;
s[i][h[i]]=true;
}
else{
for(int j=1;j<=h[i];j++){
s[i][j]=s[i-1][j];
}
if(s[i][h[i]]!=1){
ans++;
s[i][h[i]]=1;
}
}
}
cout<<ans<<endl;
return 0;
}