矩形覆盖 题解

heyucheng 2024-01-13 22:32:31 3 返回题目

通过题目可以知道要定若干个矩阵,使这个不规则图形充满。

不难想到,为了使矩阵尽量小,每一个矩阵的高应该要正好顶到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;
}
{{ vote && vote.total.up }}