uva 11456 - Trainsorting(dp,LIS)
阿新 • • 發佈:2018-12-13
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; }