UVA 11456 - Trainsorting(DP + LIS)

Problem A: Trainsorting

Erin is an engineer. She drives trains. She also arranges the cars within each train. She prefers to put the cars in decreasing order of weight, with the heaviest car at the front of the train.

Unfortunately, sorting train cars is not easy. One cannot simply pick up a car and place it somewhere else. It is impractical to insert a car within an existing train. A car may only be added to the beginning and end of the train.

Cars arrive at the train station in a predetermined order. When each car arrives, Erin can add it to the beginning or end of her train, or refuse to add it at all. The resulting train should be as long as possible, but the cars within it must be ordered by weight.

Given the weights of the cars in the order in which they arrive, what is the longest train that Erin can make?

Input Specification

The first line is the number of test cases to follow. The test cases follow, one after another; the format of each test case is the following:

The first line contains an integer 0 <= n <= 2000, the number of cars. Each of the following n lines contains a non-negative integer giving the weight of a car. No two cars have the same weight.

Sample Input

1
3
1
2
3

Output Specification

Output a single integer giving the number of cars in the longest train that can be made with the given restrictions.

Output for Sample Input

3

题意:

一些车厢,一辆辆从头到尾开进站,进站的时候可以选择接在头或者尾,或者放弃这节,但是必须保证车厢从头到尾是从大到小的,问最长能接几节。

思路:

LIS,对于每一个位置,需要找出从这个位置往后,比这个数字大的最长上升子序列和比这个数字小的最长上升子序列,dp[i]表示到i个位置以i为结尾的LIS最长是多少,然后逆序去DP即可。

代码:

#include <stdio.h>
#include <string.h>
#define max(a,b) ((a)>(b)?(a):(b))

const int N = 2005;
int t, n, train[N], dp1[N], dp2[N];

int solve() {
	int ans = 0;
	for (int i = n; i >= 1; i--) {
		dp1[i] = dp2[i] = 1;
		for (int j = n; j > i; j--) {
			if (train[i] > train[j])
				dp1[i] = max(dp1[i], dp1[j] + 1);
			else
				dp2[i] = max(dp2[i], dp2[j] + 1);
		}
		ans = max(ans, dp1[i] + dp2[i] - 1);
	}
	return ans;
}

int main() {
	scanf("%d", &t);
	while (t--) {
		scanf("%d", &n);
		for (int i = 1; i <= n ; i++)
			scanf("%d", &train[i]);
		printf("%d\n", solve());
	}
	return 0;
}


  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值