1. 程式人生 > >uva 11456 - Trainsorting(dp,LIS)

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;
}