1. 程式人生 > >HDU 5696 區間的價值 (DFS)

HDU 5696 區間的價值 (DFS)

區間的價值

Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 136    Accepted Submission(s): 66


Problem Description
我們定義“區間的價值”為一段區間的最大值*最小值。
一個區間左端點在L,右端點在R,那麼該區間的長度為(RL+1)
現在聰明的傑西想要知道,對於長度為k的區間,最大價值的區間價值是多少。
當然,由於這個問題過於簡單。
我們肯定得加強一下。
我們想要知道的是,對於長度為1n的區間,最大價值的區間價值分別是多少。
樣例解釋:
長度為1
的最優區間為22 答案為66
長度為2的最優區間為45 答案為44
長度為3的最優區間為24 答案為26
長度為4的最優區間為25 答案為26
長度為5的最優區間為15 答案為16
Input 多組測試資料
第一行一個數n(1n100000)
第二行n個正整數(1ai109),下標從1開始。
由於某種不可抗力,ai的值將會是1109內隨機產生的一個數。(除了樣例)
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]);
    }
}