UVA-10131

题意:

       输入一些大象的的重量和智商,找出满足:按重量严格递增,智商严格递减(严格递减的意思就是只能小于,不能等于)的最长的序列。

解法:

      参照小白书上的方法,将问题转换为求DAG上的最长路径问题(此题显然不存在自环、闭环以及重复边,因此可以转换为DAG问题)。

      DAG使用邻接矩阵G存放,G[i][j] = true表示第i头大象重量大于第j头大象,且第i头大象智商小于第j头大象。

     注意此题的最长路径是不固定起点和终点的,这里用的是记忆化DP(dijkstra等算法当然也能行得通)。使用DP[i]表示从i出发的最长路径,状态转移方程简单来讲就是:

从i出发的最长路径 = 所有i的邻居中最长路径 + 1。 

即 DP[i] = max(DP[j] + 1), G[i][j] == true。

#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
bool G[1001][1001];
int DP[10010], n;
int dp(int i)
{
	if (DP[i] > 0) return DP[i];
	int k = 1;
	for (int j = 1; j <= n; j++) if(G[i][j]) 
		k = max(k,1 + dp(j));
	return DP[i] = k;
}
void printg(int i)
{
	cout << i << endl;
	for (int j = 1; j <= n; j++)  if (G[i][j]&&DP[j] + 1 == DP[i])
	{
		printg(j); break;
	}
}
int main()
{
	int a[1001][2], mi = 0;
	memset(G, 0, sizeof(G)); memset(DP, 0, sizeof(DP));
	for (n = 1; cin >> a[n][0] >> a[n][1]; n++);
	for (int i = 1; i <= n; i++) for (int j = i + 1; j <= n; j++)
	{
		G[i][j] = (a[i][0]<a[j][0] && a[i][1]>a[j][1]) ? true : false;
		G[j][i] = (a[j][0]<a[i][0] && a[j][1]>a[i][1]) ? true : false;
	}
	for (int i = 1; i <= n; i++)
		if (dp(i) > DP[mi]) mi = i;
	cout << DP[mi] << endl;   printg(mi);
	return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_42103284/article/details/108392242