区间的价值
Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 136 Accepted Submission(s): 66
Total Submission(s): 136 Accepted Submission(s): 66
Problem Description
我们定义“区间的价值”为一段区间的最大值*最小值。
一个区间左端点在 L ,右端点在 R ,那么该区间的长度为 (R−L+1) 。
现在聪明的杰西想要知道,对于长度为 k 的区间,最大价值的区间价值是多少。
当然,由于这个问题过于简单。
我们肯定得加强一下。
我们想要知道的是,对于长度为 1∼n 的区间,最大价值的区间价值分别是多少。
样例解释:
长度为 1 的最优区间为 2−2 答案为 6∗6
长度为 2 的最优区间为 4−5 答案为 4∗4
长度为 3 的最优区间为 2−4 答案为 2∗6
长度为 4 的最优区间为 2−5 答案为 2∗6
长度为5的最优区间为 1−5 答案为 1∗6
一个区间左端点在 L ,右端点在 R ,那么该区间的长度为 (R−L+1) 。
现在聪明的杰西想要知道,对于长度为 k 的区间,最大价值的区间价值是多少。
当然,由于这个问题过于简单。
我们肯定得加强一下。
我们想要知道的是,对于长度为 1∼n 的区间,最大价值的区间价值分别是多少。
样例解释:
长度为 1 的最优区间为 2−2 答案为 6∗6
长度为 2 的最优区间为 4−5 答案为 4∗4
长度为 3 的最优区间为 2−4 答案为 2∗6
长度为 4 的最优区间为 2−5 答案为 2∗6
长度为5的最优区间为 1−5 答案为 1∗6
Input
多组测试数据
第一行一个数 n(1≤n≤100000) 。
第二行 n 个正整数 (1≤ai≤109) ,下标从 1 开始。
由于某种不可抗力, ai 的值将会是 1∼109 内随机产生的一个数。(除了样例)
第一行一个数 n(1≤n≤100000) 。
第二行 n 个正整数 (1≤ai≤109) ,下标从 1 开始。
由于某种不可抗力, ai 的值将会是 1∼109 内随机产生的一个数。(除了样例)
Output
输出共
n
行,第
i
行表示区间长度为
i
的区间中最大的区间价值。
Sample Input
5 1 6 2 4 4
Sample Output
36 16 12 12 6
Source
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5696
题目分析:DFS拿最小值的位置去分割区间,求包含当前最小值长度的区间的最大价值,最后把没分割到的区间更新一下,显然小区间的值要比大区间的大
#include <cstdio>
#include <cstring>
#include <algorithm>
#define ll long long
using namespace std;
int const MAX = 1e5 + 5;
ll a[MAX], ans[MAX];
int n;
void DFS(int l, int r)
{
if(l >= r)
return;
ll mi = 0x3fffffff, ma = 0;
int mipos = 0, mapos = 0;
for(int i = l; i <= r; i++)
{
if(mi > a[i])
{
mi = a[i];
mipos = i;
}
if(ma < a[i])
{
ma = a[i];
mapos = i;
}
}
ans[r - l + 1] = max(ans[r - l + 1], mi * ma);
DFS(l, mipos - 1);
DFS(mipos + 1, r);
}
int main()
{
while(scanf("%d", &n) != EOF)
{
memset(ans, 0, sizeof(ans));
for(int i = 1; i <= n; i++)
{
scanf("%lld", &a[i]);
ans[1] = max(ans[1], a[i] * a[i]);
}
DFS(1, n);
for(int i = n - 1; i >= 1; i--)
ans[i] = max(ans[i], ans[i + 1]);
for(int i = 1; i <= n; i++)
printf("%lld\n", ans[i]);
}
}