UVa 497 - Strategic Defense Initiative

题目:最大上升子序列。输出一组解。

分析: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;
}

posted @ 2016-03-24 11:11  mengfanrong  阅读(363)  评论(0编辑  收藏  举报