zju 1108

大意是说给定n个数对(w1,s1),(w2,s2),(w3,s3)......(wn,sn)
现在要求一个序列(a1,a2,a3,...,am)使得有
Wa1<Wa2<Wa3<Wa4<。。。<Wam
Sa1>Sa2>Sa3>Sa4>。。。>Sam
现在要求出这个序列的最大长度,并且输出序列中的元素。
典型的DP,关键是这里是数对,将数对的第一个元素w从小到达的顺序来对数对排一次序,这样我们就可以不用考虑第一个数了,问题变成了典型的最长单调自序列问题。

my code:
#include <iostream>
using namespace std;

#define MAXN 1000
struct mice {
    
int w,s;
    
int id;
};
bool operator<const mice& m1,const mice& m2 ) {
    
if( m1.w<m2.w )
    
return true;
    
if( m1.w==m2.w )
    
return m1.s>m2.s;
    
return false;
}

mice m[ MAXN
+1 ];   //数对
int p[ MAXN+1 ];    //记录结果

void print( int id ) {
    
if( id==0 ) return;
    print( p[ id ] );
    
if( p[ id ]==0 )
    cout
<<m[ id ].id<<endl;
    
else if( m[ p[id] ].s>m[ id ].s&&m[ p[ id ] ].w<m[ id ].w ) 
    cout
<<m[id].id<<endl;
}
int main(  ) {
    
int w,s;
    
int id=0;
    
int l[ MAXN+1 ];       //DP用的数组
    while( cin>>w>>s ) {
    id
++;
    m[ id ].w
=w;
    m[ id ].s
=s;
    m[ id ].id
=id;
    }
    sort( m
+1,m+id+1 );
    l[ 
0 ]=0;
    
forint i=1;i<=id;i++ )
    l[ i ]
=1;
    
//DP
    forint i=1;i<=id;i++ )
    
forint j=1;j<i;j++ ) {
        
if( m[ j ].s>m[ i ].s&&m[ j ].w<m[ i ].w&&l[ j ]+1>l[ i ] ) {
        l[ i ]
=l[ j ]+1;
        p[ i ]
=j;
            }
    }
    
int maxid=1;
    
forint i=2;i<=id;i++ )
    
if( l[ i ]>l[ maxid ] )
        maxid
=i;
    cout
<<l[ maxid ]<<endl;
    print( maxid );
    
return 0;
}

posted on 2007-07-19 18:55  woodfish  阅读(377)  评论(0编辑  收藏  举报

导航