您的位置:首页 > 其它

zju 1108

2007-07-19 18:55 246 查看
大意是说给定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;
for( int i=1;i<=id;i++ )
l[ i ]=1;
//DP
for( int i=1;i<=id;i++ )
for( int 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;
for( int i=2;i<=id;i++ )
if( l[ i ]>l[ maxid ] )
maxid=i;
cout<<l[ maxid ]<<endl;
print( maxid );
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: