rqnoj 26 合唱队形 (dp lis)

最近好颓废,都没什么刷题,虽然老是抱着算法书看,其实看没多少进去。。。

而且上周特别忙,什么建模,还有个朋友叫我帮弄下视频什么的,翘了几节课,熬了几个夜,加上什么院运会,实在够呛,今天终于解放了,虽然四级也快来了,也要分散一些重心,总之我开始重新开始刷题了。。。

这题是上一周做的。。。今天又做了一遍,换了个好点的算法。。。

凡是我做的题都是水题,所以这也是个水题,dp水题,初级LIS。

第一次做我正火热地做LCS,于是用很挫的算法,因为听说LIS可以用LCS做,于是把原数组和排过序的数组求LCS,水过了。。。复杂度n^3。。。由于很挫,我就不放出来了。。。

我看学长用了另外一种算法,复杂度降了一级,n^2。。。

其实只要从左向右求LIS,然后从右向左再逆着求一次LIS,然后循环对应的数加起来的数,就是对应的那个人为中间最高时的排队人数+1。

AC代码:

#include <cstdio>
const int maxn = 110;
int n, max, a[maxn], b[maxn], c[maxn], i, j;
int main()
{
	scanf("%d", &n);
	for (i = 0; i < n; i++)
		scanf("%d", &a[i]);
	for (i = 0; i < n; i++)	//increace from left
	{
		b[i] = 1;
		for (j = 0; j < i; j++)
			if (a[i] > a[j] && b[j] + 1 > b[i])
				b[i] = b[j] + 1;
	}
	for (i = 1; i <= n; i++)	//increace from right 
	{
		c[n - i] = 1;
		for (j = n - 1; j > n - i; j--)
			if (a[n - i] > a[j] && c[j] + 1 > c[n - i])
				c[n - i] = c[j] + 1;
	}
	for (i = 0; i < n; i++)
		if (b[i] + c[i] > max)
			max = b[i] + c[i];
	printf("%d\n", n - max +1);
	return 0;
}



原文地址:https://www.cnblogs.com/java20130723/p/3212157.html