ALDS1_1_D Maximum Profit
阿新 • • 發佈:2018-12-24
題目連結
題目大意
給出一列數, 輸出最大值
題目的坑
看似很簡單, 直接兩層for迴圈就可以搞定了, 但這會超時。(因為我就是這麼做的..0.0)
典型的錯誤示例...
#include<iostream> #include<stack> #include<cstring> #include<cstdio> #include<algorithm> #include<cmath> using namespace std; int N; int a[200005]; int main() { scanf("%d", &N); for (int i = 0; i < N; i++) scanf("%d", &a[i]); int maxn = a[1] - a[0]; for (int i = 0; i < N-1; i++) for (int j = i + 1; j < N; j++) maxn = max(maxn, a[j] - a[i]); cout << maxn << endl; return 0; }
如果用以上解法則時間複雜度約達到了 , 肯定是過不去的。所以得進行優化, 那這裡怎麼進行優化呢?
如果我們每找一次最大值, 並同時儲存當前的最小值, 就可以少一個for迴圈, 時間複雜度約為, 可能這麼說還不是太明白.
舉個例子: 假如這裡有一些數字 5,3,1,3,4,3 , 一開始我們取一個很小的數為最大值(比如maxn=-1e9),minn=5為最小值(只是一開始的預備處理, 後面會不斷更新的), 現在進入for迴圈開始找最大值, 首先是3-5和-1e9比較取最大值, 那麼現在的最大值是3-5(=-2), 同時儲存當前的最小值, 即再加上一條語句, minn=(3,minn), 則此時最小值為3, 那麼當進入下一次迴圈, 直接讓1-3 就可以了, 還會讓1-5嗎,這就沒意義了,因為3比5小, 減去越小的數字則結果會越大.
如果還不懂, 則要細細的品嚐程式碼~
#include<iostream> #include<stack> #include<cstring> #include<cstdio> #include<algorithm> #include<cmath> using namespace std; int N; int a[200005]; int main() { scanf("%d", &N); for (int i = 0; i < N; i++) scanf("%d", &a[i]); int maxn = a[1]-a[0]; //這裡我以a[1]-a[0]為初始的最大值 int minn = a[0]; for (int i = 1; i < N; i++) { maxn = max(maxn, a[i] - minn); //a[i]減去當前最小值的結果 就是當前的最大值 minn = min(a[i], minn); } cout << maxn << endl; return 0; }
如果你覺得這樣開這麼大的陣列去存資料浪費記憶體的話, 其實還可以再一次優化, 可以減少空間複雜度(親測可行^.^)
#include<iostream>
#include<stack>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<cmath>
using namespace std;
int N;
int a;
int main()
{
scanf("%d", &N);
int maxn = (int)-1e9, minn;
for (int i = 0; i < N; i++)
{
scanf("%d", &a);
if (i == 0) //i==0 主要就是設定第一個數字為最小值, 便直接進入下一次迴圈
{
minn = a;
continue;
}
maxn = max(maxn, a - minn); //a[i]減去當前最小值的結果 就是當前的最大值
minn = min(a, minn);
}
cout << maxn << endl;
return 0;
}