您的位置:首页 > 其它

TOJ 1772

2013-12-07 11:21 441 查看
题目连接 :

 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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  动态规划