uva 11456 - Trainsorting(dp,LIS)

https://vjudge.net/problem/UVA-11456

题意
   艾琳是个开火车的机师,她也负责车厢的调度。她喜欢把车厢依重量由大到小排列,把最重的车厢摆在火车的前方。
   不幸的是,排列车厢并不容易。你不能直接把一截车厢拿起来放在别处。把一截车箱插入现有的列车中间并不切实际。一截车厢仅能接在列车的前面或后面。
   车厢以事先排定的顺序抵达车站。当一截车厢抵达时,艾琳可以把它接在列车的前方或后方,或根本不要这截车厢。列车越长越好,但是其中的车厢要依重量排列。
   依车厢抵达的顺序给你车厢的重量,艾琳所能接出的最长火车是多长?

 思路: 比如 7 9 5 6 4 8 这个例子,平凡的做法是先取一个数字,比如5,那么在5出现前先找大于5最长上升子序列,在5出现后,再找到小于5的下降子序列,并且那个上升子序列继续上升。或者在5出现前是小于5的下降子序列,5出现后再找大于5的上升,刚才那个下降的序列继续下降。因此,我们先按照出现顺序标记,然后按照重量排序,可以使用STL中的map,然后以5为分界,那么前面的都小于5,后面的都大于5. 前面从头到尾计算下降,后面从未到前计算下降。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#include<vector>
#include<algorithm>
#include<map>
using namespace std;
#define MAX 2005
int main() {
	int n,t;
	map<int,int> imap;
	cin>>t;
	vector<int> uplist,downlist,sq;
	map<int,int>::iterator it;
	while(t--) {
		cin>>n;
		int tn=0;
		int w;
		imap.clear();
		while(tn<n) {
			cin>>w;
			imap.insert(make_pair(w,++tn));
		}
		//second的最大下降子序列
		uplist.resize(n);
		sq.clear();
		it=imap.begin();
		for(it; it!=imap.end(); it++) {
			sq.push_back(it->second);
		}
		for(int i=0; i<n; i++) {
			uplist[i]=1;
			for(int j=0; j<i; j++)
				if(sq[i]<sq[j]) {
					uplist[i]=max(uplist[j]+1,uplist[i]);
					//break;
				}
		}
		//second的最大下降子序列  逆方向
		downlist.resize(n);
		for(int i=n-1; i>-1; i--) {
			downlist[i]=1;
			for(int j=n-1; j>i; j--)
				if(sq[i]<sq[j]) {
					downlist[i]=max(downlist[j]+1,downlist[i]);
					//break;
				}
		}
		int imax=0;
		for(int i=0; i<n; i++) {
			imax=max(imax,uplist[i]+downlist[i]-1);
		}
		cout<<imax<<endl;
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/qiang_____0712/article/details/84974540