2019.9.11 小米笔试算法岗编程题 两个动归
1.最大連續子序列之和
時間限制:C/C++語言 1000MS;其他語言 3000MS
內存限制:C/C++語言 65536KB;其他語言 589824KB
題目描述:
給定K個整數的序列{ N1, N2, …, NK },其任意連續子序列可表示為{ Ni, Ni+1, …, Nj },其中 1 <= i <= j <= K。最大連續子序列是所有連續子序中元素和最大的一個, 例如給定序列{ -2, 11, -4, 13, -5, -2 },其最大連續子序列為{ 11, -4, 13 },最大和為20
輸入:
一個整數數組
輸出:
最大的和
樣例:
輸入: 1 2 3 輸出: 6思路:
動態規劃經典例題。
dp[i]代表,使用了num[i]的子序列,最大和為多少。
既然dp[i]使用了num[i],那么dp[i+1]即為使用num[i+1],則這個子序列要么只有num[i+1]一個數,要么從上一個使用了num[i]的子序列接過來。(只要是非負數,怎么拿都不虧,負數才會出現問題)
∴dp[i] = max( dp[i-1]+num[i] , num[i])
代碼:
#include <cstdio> #include <string> #include <iostream> #include <cstring> #include <algorithm> using namespace std; int dp[100010]; int a[100010]; int n; int split(string &s,int a[]) {int n = 0;int res = 0;int k = 1;s += ' ';for(int i=0;i<s.size();i++){if(s[i]=='-'){k = -1;continue;}if('0'<=s[i] && s[i]<='9'){res = res*10 + s[i]-'0';}else{a[++n] = k*res;res = 0;k = 1;}}return n; } int main() {string input;getline(cin,input);n = split(input,a);for(int i=1;i<=n;i++)dp[i] = max(0,a[i]);int max_num = 0;for(int i=1;i<=n;i++){dp[i] = max(dp[i-1]+a[i],dp[i]);max_num = max(max_num,dp[i]);}cout<<max_num<<endl;return 0; }A了。難點在處理輸入。
2.利潤最大化
時間限制:C/C++語言 1000MS;其他語言 3000MS
內存限制:C/C++語言 65536KB;其他語言 589824KB
題目描述:
米兔是一個投資人,持有著小米的股票。股票價格每日都有波動,數組price代表了每日股票的具體價格,其中price[i]代表小米在第i天的股價。米兔最多可以進行兩次交易(一個買進,賣出為一次交易)并且不能同時進行兩次交易(必須在再次購買前出售掉之前的股票),米兔想知道他最多能夠獲得多少利潤呢?
輸入:
正整數序price,代表了股票價格。其中第i個數代表了第i天的價格。
輸出:
兩次交易后能獲得的最大利潤
樣例:
輸入: 2 1 5 0 2 3 1 4 輸出: 8思路:
枚舉中間分隔,兩頭分別用前綴最小和后綴最大,最后再看看有沒有只交易一輪的。其實一開始以為要開線段樹來拿區間極值,寫完線段樹后發現用不上。這個算法效率不高,基本相當于暴力。
代碼:
#include <cstdio> #include <string> #include <iostream> #include <cstring> #include <algorithm> using namespace std; const int MAXNUM = 100010; int a[MAXNUM]; int n; int split(string &s,int a[]) {int n = 0;int res = 0;int k = 1;s += ' ';for(int i=0;i<s.size();i++){if(s[i]=='-'){k = -1;continue;}if('0'<=s[i] && s[i]<='9'){res = res*10 + s[i]-'0';}else{a[++n] = k*res;res = 0;k = 1;}}return n; } int dp[MAXNUM],min_v[MAXNUM],max_v[MAXNUM]; int main() {string input;getline(cin,input);n = split(input,a);int max_num = 0;memset(min_v,0x3f,sizeof(min_v));for(int i=1;i<=n;i++)min_v[i] = min(a[i],min_v[i-1]);for(int i=n;i>=1;i--)max_v[i] = max(a[i],max_v[i+1]);for(int key=2;key<=n-2;key++)//枚舉中間{int tempL = 0;for(int i=1;i<=key;i++){tempL = max(tempL, a[i]-min_v[i]);}int tempR = 0;for(int i=n;i>=key+1;i--){tempR = max(tempR, max_v[i]-a[i]);}max_num = max(max_num, tempL+tempR);}for(int i=1;i<=n;i++){max_num = max(max_num, a[i]-min_v[i]);}cout<<max_num<<endl;return 0; }A了,不知道數據范圍有多少,這個應該是O(n2)的。笑死我了,一開始寫了4重for循環O(n^4)的,竟然能過77%。
int max_num = 0;for(int i=1;i<=n-1;i++)for(int j=i+1;j<=n;j++)for(int k=j;k<=n;k++)for(int l=k+1;l<=n;l++)max_num = max(max_num,a[j]-a[i] + a[l]-a[k]);cout<<max_num<<endl;總結
以上是生活随笔為你收集整理的2019.9.11 小米笔试算法岗编程题 两个动归的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python 读写csv文件(创建、追加
- 下一篇: SparkStreaming编程