【codechef】每次将l-r修剪成一样高度,求最少修剪几次

Example Input


4
3
3 1 3
2 1 2
7
1 3 4 5 1 2 3
1 2 1 2 1 1 1
3
2 3 9
2 3 9
2
1 2
2 1

Example Output


2
3
0
-1

这题一看和涂色问题很像。但后来我发现两者是有区别的。涂色可以任意覆盖,而修剪只能越剪越短,不可能再变长。并且数据范围有10^5,肯定不是像涂色问题一样用区间dp。所以我后来用双端队列来维护可以沿用到当前这棵树的修剪高度,这个队列一定是递减(想想就知道了只能越剪越短啊)。要考虑的有点多,如果沿用修剪高度的话,原始高度一定要不小于修剪高度,最终高度必须保证不大于修剪高度。因此必须用双端队列而不能用栈。做法有点贪心的思想。

思考时间有点久。

#include<bits/stdc++.h>
using namespace std;  
int x[100005];
int y[100005];
deque<int> st;
int main(){
	int t;
	cin>>t;
	while(t--){
		while(!st.empty()) st.pop_back();
 		int n;
		cin>>n;
		for(int i=0;i<n;++i) cin>>x[i];
		int u=0;
		for(int i=0;i<n;++i){
			cin>>y[i];
			if(y[i]>x[i]) u=1;
		} 
		if(u==1){
			cout<<-1<<endl;
			continue;
		}
		int s=0;
		for(int i=0;i<n;++i){
			while(!st.empty()&&st.front()>x[i]) st.pop_front();
			while(!st.empty()&&st.back()<y[i]) st.pop_back();
			if(x[i]==y[i]) continue;
			if(!st.empty()&&st.back()==y[i]) ;
			else s++;
			st.push_back(y[i]);
		}
		cout<<s<<endl;
	}
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值