1. 程式人生 > >【貪心】LIS @The 15th Zhejiang Provincial Collegiate Programming Contest E

【貪心】LIS @The 15th Zhejiang Provincial Collegiate Programming Contest E

傳送門

題意要你構造一個序列,使得該序列的每個位置上的最長上升子序列的長度能構成給定的序列。
構造序列的元素要求還要求滿足給定的上下界

solution
我們可以把給出的最長上升子序列的長度按升序排列,長度相同的按下標降序排列。
排完序後第一個數可以貪心的取其下界,同一層(即長度相同)的下標小的取值應該大於等於下標較大的取值
同時取值應該大於前一層下標最大且小於該位置的數

#define IN_LB() freopen("F:\\in.txt","r",stdin)
#define IN_PC() freopen("C:\\Users\\hz\\Desktop\\in.txt","r",stdin)
#include <bits/stdc++.h> using namespace std; const int maxn = 100005; struct node { int ind,ceil,d,u; int ans; } nd[maxn]; bool cmp(node a,node b) { if(a.ceil==b.ceil)return a.ind>b.ind; return a.ceil<b.ceil; } bool cmp1(node a,node b) { return a.ind<b.ind; } struct
qnode{ int yuanind,xianind,ceil; }; queue <qnode> que; int main() { // IN_LB(); int T; scanf("%d",&T); while(T--) { int n; scanf("%d",&n); for(int i=0; i<n; i++) { nd[i].ind = i; scanf("%d",&nd[i].ceil); } for
(int i=0; i<n; i++) { scanf("%d%d",&nd[i].d,&nd[i].u); } sort(nd,nd+n,cmp); nd[0].ans = nd[0].d; qnode seed; seed.yuanind = nd[0].ind; seed.xianind = 0; seed.ceil = 1; while(!que.empty())que.pop(); que.push(seed); for(int i=1; i<n; i++) { if(nd[i].ceil==nd[i-1].ceil) { if(nd[i].ceil>1){ int exind; while(!que.empty()) { if(que.front().yuanind<nd[i].ind) { exind = que.front().xianind; break; } que.pop(); } nd[i].ans = max(max(nd[exind].ans+1,nd[i-1].ans),nd[i].d); } else nd[i].ans = max(nd[i-1].ans,nd[i].d); qnode cur; cur.yuanind = nd[i].ind; cur.xianind = i; cur.ceil = nd[i].ceil; que.push(cur); } else { int exind; while(!que.empty()) { if(que.front().ceil==nd[i].ceil-1&&que.front().yuanind<nd[i].ind) { exind = que.front().xianind; break; } que.pop(); } nd[i].ans = max(nd[exind].ans+1,nd[i].d); qnode cur; cur.yuanind = nd[i].ind; cur.xianind = i; cur.ceil = nd[i].ceil; que.push(cur); } } sort(nd,nd+n,cmp1); for(int i=0; i<n; i++) { printf("%d%s",nd[i].ans,(i==n-1)?"\n":" "); } } return 0; }