TOJ 1772


题目连接 :

 http://acm.tzc.edu.cn/acmhome/problemdetail.do?&method=showdetail&id=1772


题目类型:

动态规划 - 最优子段


数据结构: 

struct LMIC_ARR
{
	__int64 vle;
	
	/* 记录arr[i]的左界和右界 */
	int s, e;
};


思路分析:

动态规划思想, 不过个人觉得比较像暴力,

输入一串数列,arr : a1,a2,a3......an

记录每一个 ai 大于等于它的 左右界,

直接用2次for 中间加while 左右循环的找

直到找到比ai小的数字停止.就是它的界

最后选取个最大值的 右界-左界 * 它自身的数值 就是答案

---------------------------------------------------------------------------

我想到这个方法的时候觉得会超时 所以没敢试,

但从网上得来的代码证明, 这样不会超时, 我也不知道为什么

理论来说 最坏时间 应该是 N^2 



证明:

类似暴力破解, 证明 略


源代码:

#include <iostream>
#include <stdio.h>

using namespace std;

struct LMIC_ARR
{
	__int64 vle;
	
	/* 记录arr[i]的左界和右界 */
	int s, e;
};

int main()
{
	int i, n, tmp;
	LMIC_ARR arr[100005];
	
	while( scanf( "%d", &n ), n )
	{
		for( i = 1; i <= n; i ++ )
		{
			scanf( "%I64d", &arr[i].vle );
			
			tmp = i;
			
			if( tmp == 1 )
			{
				arr[i].s = 1;
			}
			else
			{
				while( tmp > 1 && arr[i].vle <= arr[tmp - 1].vle )
				{
					tmp = arr[tmp - 1].s;
				}
				arr[i].s = tmp;
			}
		}
		
		for( i = n ; i >= 1; i -- )
		{
			tmp = i;
			
			if( tmp == n )
			{
				arr[i].e = n;
			}
			else
			{
				while( tmp < n  && arr[i].vle <= arr[tmp + 1].vle )
				{
					tmp = arr[tmp + 1].e;
				}
				arr[i].e = tmp;
			}
		}
		
		__int64 max = -1;
		
		for( i = 1; i <= n ; i ++ )
		{
			__int64 snt = ( arr[i].e - arr[i].s + 1 ) * arr[i].vle;
			
			max >?= snt;
		}
		
		printf( "%I64d\n", max );
	}
	
	return 0;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值