题目:最大上升子序列,输出一组解。
分析:dp,LIS。数据较小 O(n^2)算法即可。
设以第i个数字作为最大上升子序列中的最后一个数的长度为 f(i),则有转移方程:
f(i)= max(f(j)) { 0=< j < i && data[j] < data[i] };
用一个数组记录前驱,递归输出即可。
说明:注意输出格式有点纠结。
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
using namespace std;
char buf[256];
int data[10000];
int dp[10000];
int front[10000];
void output( int d, int s )
{
if ( front[s] >= s )
printf("Max hits: %d\n",d+1);
else
output( d+1, front[s] );
printf("%d\n",data[s]);
}
int main()
{
int n;
while (~scanf("%d",&n)) {
getchar();
getchar();
while ( n -- ) {
char ch;
int count = 0;
while (gets(buf) && buf[0])
data[count ++] = atoi(buf);
for ( int i = 0 ; i < count ; ++ i ) {
dp[i] = 1;
front[i] = i;
for ( int j = 0 ; j < i ; ++ j )
if ( data[i] > data[j] && dp[i] < dp[j]+1 ) {
dp[i] = dp[j]+1;
front[i] = j;
}
}
int max = 0;
for ( int i = 1 ; i < count ; ++ i )
if ( dp[i] > dp[max] )
max = i;
if ( count )
output( 0, max );
else printf("Max hits: 0\n");
if ( n ) printf("\n");
}
}
return 0;
}