uva481 What Goes Up

/*
    uva481 What Goes Up
    AC By Warteac
    2013-4-8
    Runtime:0.196s
*/
#include<iostream>
#include<string>
#include<sstream>
#include<vector>
#include<queue>
#include<stack>
#include<algorithm>
#include<climits>
using namespace std;
//
struct node{
    int value;
    int pred;
    node(int a = 0, int b = 0){value = a; pred = b;}
};
class WhatGoesUp{
private:
    vector<int> sequence; //altitudes
    int maxLength;
    vector<node> chain;
    int maxInex;
public:
    void initial();
    void readCase();
    void computing();
    void outResult();
};
void WhatGoesUp::initial(){
    sequence.clear();
    maxLength = 0;
    chain.clear();
}
void WhatGoesUp::readCase(){
    int x;
    string line;
    while(getline(cin, line) && (line.size() > 0)){
        stringstream(line) >> x;
        sequence.push_back(x);
    }
}
void WhatGoesUp::computing(){
    vector<int> minVisited;//存放有序序列,并且不断地覆盖,结束时的长度就是最长的长度,因为它不会被任何更长的子序列覆盖
    vector<int> numVisited;//记录minVisited[]中对应值的下标
    int t;
    numVisited.push_back(-1); //for the sentinel
    minVisited.push_back(INT_MIN);
    for(int i = 0; i < sequence.size(); i++){//nlog(n)
        //cout << sequence[i] << endl;
        t = lower_bound(minVisited.begin(), minVisited.end(), sequence[i]) - minVisited.begin();
        //cout<<"t=   "<<t<<endl;
        if(t >= minVisited.size()){ // t indicates the new length

            minVisited.push_back(sequence[i]);//记录一个序列,最可能成为目标序列但不是最终的序列

            numVisited.push_back(chain.size());//记录相应于minVisited[]的下标

            chain.push_back(node(sequence[i], numVisited[t-1]));//记录每个节点的直接前驱的下标
            //cout<<"chain.push_back(node(sequence[i], numVisited[t-1]))"<<" ( "<<sequence[i]<<','<<numVisited[t-1]<<" ) "<<endl;
        }else if(sequence[i] < minVisited[t]){//sequence[i] is the smallest

            minVisited[t] = sequence[i];//用小的替换大的,因为这样序列才会更长

            numVisited[t] = chain.size();//

            chain.push_back(node(sequence[i], numVisited[t-1]));//
		
	    	//	cout<<"chain.push_back(node(sequence[i], numVisited[t-1]))"<<" ( "<<sequence[i]<<','<<numVisited[t-1]<<" ) "<<endl;
        }
    }
    maxLength = numVisited.size() - 1;//

//	cout<<"maxLength ="<<maxLength<<endl;
//	cout<<"maxLength ="<<minVisited.size() - 1<<endl;
    maxInex = numVisited[maxLength];
}
void WhatGoesUp::outResult(){
    cout <<  maxLength <<endl;
    cout<< '-' << endl;
    stack<int> s;
    int p = maxInex;
    while(p > -1){
        s.push(chain[p].value);
        p = chain[p].pred;
    }
    while(!s.empty()){
        cout << s.top() << endl;
        s.pop();
    }
}
//
int main(){
    WhatGoesUp wgu;
    wgu.initial();
    wgu.readCase();
    wgu.computing();
    wgu.outResult();
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值