codefoces 1407D Discrete Centrifugal Jumps

https://codeforces.com/contest/1407/problem/D

这神仙题啊,举个例子

4 5 6 5 6 3

这样的序列如何建边?

//先只考虑中间部分比i  j大的

4

4 5       4---5

4 5 6    5---6

4 5 5    5---5

4 5

4 5 6              5---6

3               4  5  6  --- 3 (4 5 6都连3)

建好图跑bfs吧

#include<iostream>
#include<vector>
#include<algorithm>
#include<stack>
#include<queue>
using namespace std;
typedef long long ll;
const int maxn = 3e5+11;
int n,list[maxn];
stack<int>ins;
vector<int>G[maxn];
void add(int x,int y){
	G[x].push_back(y);
}
int vis[maxn];
int bfs(){
	queue<int>que;
	que.push(1);
	vis[1] = 1;
	while(que.size()){
		int x = que.front();
		que.pop();
		for(int i=0;i<G[x].size();i++){
			int p = G[x][i];
			if(vis[p] == 0) {
				vis[p] = vis[x] + 1;
				que.push(p);
			}
		}
	}
	return 0;
}

int main(){
	
	cin>>n;
	for(int i=1;i<=n;i++){
		cin>>list[i];
	}
	for(int i=1;i<n;i++){
	//	add(i,i+1);
	}
	
	for(int i=1;i<=n;i++){
		if(ins.size() == 0){
			ins.push(i);
		}
		else{
			while(ins.size() && list[ins.top()] > list[i]){
				add(ins.top(),i);
				ins.pop();
			}
			if(ins.size()) add(ins.top(),i);
			while(ins.size() && list[ins.top()] == list[i]){//相等不能连边 
				ins.pop();
			}
			
			ins.push(i);	
		}
	}	
	
	
	while(ins.size()) ins.pop();
	 
	for(int i=1;i<=n;i++){
		if(ins.size() == 0){
			ins.push(i);
		}
		else{
			while(ins.size() && list[ins.top()]  < list[i]){
				add(ins.top(),i);
				ins.pop();
			}
			if(ins.size()) add(ins.top(),i);
			while(ins.size() && list[ins.top()] == list[i]){//相等不能连边 
				ins.pop();
			}
			//if(ins.size()) add(ins.top(),i);
			ins.push(i);	
		}
	}
//	for(int i=1;i<=n;i++){
//		for(int j=0;j<G[i].size();j++){
//			cout<<list[i]<<" "<<list[G[i][j]]<<endl;
//		}
//	}
	bfs();
	cout<<vis[n]-1<<endl;
	
	
	return 0;
}

  

寻找真正的热爱
原文地址:https://www.cnblogs.com/lesning/p/13675098.html