程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> hdu 1506(動態規劃,很棒的優化)

hdu 1506(動態規劃,很棒的優化)

編輯:C++入門知識

這道題直接按照一般的思路去算是要超時的,必須經過一定程度的優化。

對於a[i],我們需要記錄的是他之前和之後最大的連續的值比a[i]大的長度,如果每次都一個個去比對,數據大小是100000,時間復雜度是O(n^2),超時那是必然的。但是其實對於a[i]來說,如果去求後面連續的值,完全沒必要一個個去比對,直接看a[i-1]的值就行了。

比如說2、3、4、5這個序列,如果我們要看3往後能延伸多長,並不需要去逐個和4和5比較,在計算4的時候,我們已經計算過5是比4大的,因為3比4小,4所能往後延伸的長度,3也一定能達到(4能延伸的長度內的數據都大於等於4,當然也都比3大),我們可以直接比較在4達到的最終長度的末端之後的值。

這道題計算的時候進制轉換也需要特別注意,如果temp沒有強制轉換成__int64位,提交會wa。

這道題優化的思路非常巧妙,很值得學習。


[cpp]
#include<stdio.h>  
#define N 100005  
int a[N],s[N],e[N]; 
int main() 

    int n; 
    while(scanf("%d",&n),n) 
    { 
        int i; 
        for(i=0;i<n;i++) 
        { 
            scanf("%d",&a[i]); 
            s[i]=e[i]=i; 
        } 
        for(i=0;i<n;i++) 
        { 
            while(s[i]>=1&&a[s[i]-1]>=a[i]) 
                s[i]=s[s[i]-1]; 
        } 
        for(i=n-1;i>=0;i--) 
        { 
            while(e[i]<n-1&&a[e[i]+1]>=a[i]) 
                e[i]=e[e[i]+1]; 
        } 
        __int64 ans; 
        ans=0; 
        for(i=0;i<n;i++) 
        { 
            __int64 temp; 
            temp=(__int64)(e[i]-s[i]+1)*a[i];//這裡需要進行強制轉換。  
            if(temp>ans) 
                ans=temp; 
        } 
        printf("%I64d\n",ans); 
    } 
    return 0; 

#include<stdio.h>
#define N 100005
int a[N],s[N],e[N];
int main()
{
 int n;
 while(scanf("%d",&n),n)
 {
  int i;
  for(i=0;i<n;i++)
  {
   scanf("%d",&a[i]);
   s[i]=e[i]=i;
  }
  for(i=0;i<n;i++)
  {
   while(s[i]>=1&&a[s[i]-1]>=a[i])
    s[i]=s[s[i]-1];
  }
  for(i=n-1;i>=0;i--)
  {
   while(e[i]<n-1&&a[e[i]+1]>=a[i])
    e[i]=e[e[i]+1];
  }
  __int64 ans;
  ans=0;
  for(i=0;i<n;i++)
  {
   __int64 temp;
   temp=(__int64)(e[i]-s[i]+1)*a[i];//這裡需要進行強制轉換。
   if(temp>ans)
    ans=temp;
  }
  printf("%I64d\n",ans);
 }
 return 0;
}


 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved