1.非零段划分—差分灵活运用
题目链接
题意:
每次使所有大于0的区间减去一个数,这个数任意,求这个过程中左右两边都是0的最大区间数。
思路:
区间减去一个数,理所应当想到差分,但是我们需要统计符合要求的区间的个数。
正常的差分是x坐标轴上的差分,这个题是差分高度,即差分y轴上的数值
在遇见两个不同高度时,这一段差值对答案贡献度为1,在插值区间上做差分,最后求最大值
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 500010,M=10010;
int h[N],cnt[M]={0};
int n;
int main()
{
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>h[i];
if(h[i]>h[i-1])
{
cnt[h[i-1]]++;
cnt[h[i]]--;
}
}
int res=0,sum=0;
for(int i=0;i<M;i++)
{
sum+=cnt[i];
res=max(sum,res);
}
cout<<res<<endl;
}
2.岛
题目链接
可以用第一题的差分写法,亦可以枚举来写,需要加上离散化
差分写法
#include <iostream>
#include <cstring>
#include <algorithm>
#include <map>
using namespace std;
typedef pair<int, int> PII;
#define x first
#define y second
const int N = 100010;
map<int,int>p;
int h[N],n;
int main()
{
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>h[i];
if(h[i]>h[i-1])
{
p[h[i-1]]++;
p[h[i]]--;
}
}
int sum=0,res=0;
for(auto pp : p)
{
sum+=pp.second;
res=max(res,sum);
}
cout<<res<<endl;
}
枚举写法
#include <iostream>
#include <cstring>
#include <algorithm>
#include <unordered_map>
using namespace std;
typedef pair<int, int> PII;
#define x first
#define y second
const int N = 100010;
PII q[N];
int n,h[N];
int main()
{
cin>>n;
for(int i=1;i<=n;i++)cin>>h[i];
n=unique(h+1,h+n+1)-h-1;
h[n+1]=0;
for(int i=1;i<=n;i++)q[i]={h[i],i};
sort(q+1,q+n+1);
int cnt=1,res=1;
for(int i=1;i<=n;i++)
{
int k=q[i].y;
if(h[k-1]>h[k]&&h[k+1]>h[k])cnt++;
if(h[k-1]<h[k]&&h[k+1]<h[k])cnt--;
if(q[i].x!=q[i+1].x)res=max(res,cnt);
}
cout<<res<<endl;
}