hdu 1025 Constructing Roads In JGShining's Kingdom

本文探讨了最长递增子序列(LIS)问题,并详细介绍了使用动态规划解决该问题的方法。针对大规模数据集,提出了一个优化的时间复杂度为O(n*logn)的高效算法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

最长递增子序列(LIS)问题。。。

一开始我没有想到是LIS,但是知道要用dp做

我的想法是用dp[i][j]表示上面一行从第1个到第i个城市与下面一行从第1个到第j个城市之间所能修的最多路

用match[i][j]=true表示上面一行的城市i与下面一行的城市j可以修路

很容易得到状态方程:dp[i][j]=max{ dp[i-1][j], dp[i][j-1] }+match[i][j]

但题目中n的最大值是500,000因此用二维数组会超内存的


改用一维数组dp[i]表示以a[i]为最后一个元素的LIS个数,那么所有dp的最大值即为所求。

要求出所有dp,我的想法是外围循环从1到n,内层循环查找当前a[i]对应的dp[i],时间复杂度是O(n*n),所以超时


最后听炳昌大神的话看了白书上的说明,还有一个O(n*logn)的算法

对所有dp值为i的序列,取其最先结束的一个可以保证结果最优

优化的就是dp[i]的求解方法,自己看的也是一知半解,慢慢领会吧

代码如下:

#include <map>
#include <cmath>
#include <vector>
#include <string>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#define esp 1e-9
#define MAXN 500010
#define ll long long
#define INF 0x7FFFFFFF
#define BUG system("pause")
#define SW(a,b) a^=b;b^=a;a^=b;
using namespace std;
int dp[MAXN];
int a[MAXN];
int g[MAXN];
int main(void){
	int T = 0;
	int n;
	freopen("out.txt", "w", stdout);
	while(scanf("%d", &n) != EOF){
		T++;
		int poor, rich;
		for(int i=1; i<=n; ++i){
			scanf("%d %d", &poor, &rich);
			a[poor] = rich;
		}
		memset(dp, 0, sizeof(dp));
		for(int i=1; i<=n; ++i){
			g[i] = INF;
		}
		int maxdp = 0;
		for(int i=1; i<=n; ++i){
			int k = lower_bound(g+1, g+n+1, a[i]) - g;//以 a[i] 为终点时对应的dp值  
			cout << "k = " << k << endl;
			dp[i] = k;
			cout << "dp[" << i << "] = " << dp[i] << endl;
			g[k] = a[i];
			for(int j=1; j<=n; ++j) {
				if(g[j] == INF)
					break;
				cout << "g[" << j << "] = " << g[j] << endl; 
			}
			maxdp = max(maxdp, dp[i]);
		}
		
		printf("Case %d:\n", T);
		if(maxdp == 1)
			printf("My king, at most 1 road can be built.\n\n");

		else
			printf("My king, at most %d roads can be built.\n\n", maxdp);
		
	}
		
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值