UVA-10131

tech2024-08-03  47

题意:

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

解法:

      参照小白书上的方法,将问题转换为求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; }

 

最新回复(0)