HDU 5696 區間的價值 (DFS)
阿新 • • 發佈:2019-02-10
區間的價值
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,那麼該區間的長度為(R−L+1)。
現在聰明的傑西想要知道,對於長度為k的區間,最大價值的區間價值是多少。
當然,由於這個問題過於簡單。
我們肯定得加強一下。
我們想要知道的是,對於長度為1∼n的區間,最大價值的區間價值分別是多少。
樣例解釋:
長度為1
長度為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內隨機產生的一個數。(除了樣例)
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]); } }