[Hulu] 数组最大价值
題意
給定一個(gè)包含nnn個(gè)正整數(shù)的數(shù)組aaa,另外有一個(gè)長(zhǎng)度為nnn的價(jià)值數(shù)組bbb,表示第iii個(gè)正整數(shù)的價(jià)值為b[i]b[i]b[i]。我們可以選擇任意個(gè)不相交區(qū)間[i,j][i, j][i,j],需要滿足i<ji < ji<j 且a[i]=a[j]a[i] = a[j]a[i]=a[j],隨后我們可以獲得區(qū)間[i,j][i, j][i,j]所有數(shù)的價(jià)值,即b[i]+b[i+1]+...+b[j]b[i] + b[i+1] + ... + b[j]b[i]+b[i+1]+...+b[j]。
現(xiàn)在請(qǐng)輸出可以獲得的數(shù)組最大價(jià)值。
分析
此題由我改編自Hulu面試題,并上傳于Lintcode
題目鏈接
主要考察動(dòng)態(tài)規(guī)劃算法
定義數(shù)組 dp[i]dp[i]dp[i] :前i個(gè)數(shù)構(gòu)成的子數(shù)組能夠獲得的最大價(jià)值
則 dp[n]dp[n]dp[n] 即為我們需要輸出的答案。
結(jié)合題意,求解dp[i]dp[i]dp[i]時(shí)需要考慮兩種情況:
如果處理一個(gè)前綴和數(shù)組, 記為sum,那么第二種情況的dp方程可以轉(zhuǎn)化為:
dp[i]=max{dp[k?1]+sum[i]?sum[k?1]}=sum[i]+max{dp[k?1]?sum[k?1]}dp[i] = max\{dp[k-1] + sum[i] - sum[k-1]\} \\ = sum[i] + max\{dp[k-1] - sum[k-1]\}dp[i]=max{dp[k?1]+sum[i]?sum[k?1]}=sum[i]+max{dp[k?1]?sum[k?1]}
故如果在iii 前面存在多個(gè) kkk 滿足 a[i]=a[k]a[i] = a[k]a[i]=a[k], 我們只需要找到最大的 dp[k?1]?sum[k?1]dp[k-1] - sum[k-1]dp[k?1]?sum[k?1] 來(lái)轉(zhuǎn)移dpdpdp方程。
這個(gè)可以使用一個(gè)新數(shù)組MxMxMx來(lái)維護(hù),即對(duì)于每一個(gè)出現(xiàn)的數(shù)a[k]a[k]a[k],我們都維護(hù)一下: Mx[a[k]]=max{dp[k?1]?sum[k?1]}Mx[a[k]] = max\{dp[k-1] - sum[k-1]\}Mx[a[k]]=max{dp[k?1]?sum[k?1]}
那么遍歷到a[i]a[i]a[i]時(shí),只需要根據(jù) Mx[a[i]]Mx[a[i]]Mx[a[i]]的值來(lái)轉(zhuǎn)移即可。
時(shí)間復(fù)雜度: O(n)
Code
C++
const int A = 1e5 + 10; const int B = 1e3 + 10; class Solution { public:/*** @param a: The array a* @param b: The array b* @return: Return the maximum value*/int dp[A], sum[A], Mx[B];bool vis[B];int getAnswer(vector<int> &a, vector<int> &b) {// Write your code hereint n = a.size(); sum[0] = 0;for (int i = 1; i <= n; i++) {sum[i] = sum[i - 1] + b[i - 1];}memset(vis, 0, sizeof(vis));dp[0] = 0;for (int i = 1; i <= n; i++) {if (!vis[a[i - 1]]) {vis[a[i - 1]] = 1;dp[i] = dp[i - 1];Mx[a[i - 1]] = dp[i - 1] - sum[i - 1];} else {dp[i] = max(dp[i - 1], Mx[a[i - 1]] + sum[i]);Mx[a[i - 1]] = max(Mx[a[i - 1]], dp[i - 1] - sum[i - 1]);}}return dp[n];} };Java
public class Solution {/*** @param a: The array a* @param b: The array b* @return: Return the maximum value*/public int getAnswer(int[] a, int[] b) {// Write your code hereint dp[] = new int[100010];int pre[] = new int[100010];int Mx[] = new int[1010];boolean flag[] = new boolean[1010];pre[0] = 0;for (int i = 1; i <= a.length; i++) {pre[i] = pre[i - 1] + b[i - 1];}dp[0] = 0;for (int i = 1; i <= a.length; i++) {if (!flag[a[i - 1]]) {flag[a[i - 1]] = true;dp[i] = dp[i - 1];Mx[a[i - 1]] = dp[i - 1] - pre[i - 1];} else {dp[i] = max(dp[i - 1], Mx[a[i - 1]] + pre[i]);Mx[a[i - 1]] = max(Mx[a[i - 1]], dp[i - 1] - pre[i - 1]);}}return dp[a.length];}int max(int a, int b) {if (a > b) return a;return b;} }Python
class Solution:"""@param a: The array a@param b: The array b@return: Return the maximum value"""def getAnswer(self, a, b):# Write your code heres = [0 for i in range(0, len(a))]dp = [0 for i in range(0, len(a))]same = [[] for i in range(0, 1010)]same[a[0]].append(0)s[0] = b[0]for i in range(1, len(a)):s[i] = s[i - 1] + b[i]same[a[i]].append(i)maxx = 0for j in range(1, len(same[a[0]])):dp[same[a[0]][j]] = s[same[a[0]][j]]same[a[0]].pop(0)for i in range(1, len(a)):if dp[i - 1] > maxx:maxx = dp[i - 1]for j in range(1, len(same[a[i]])):if dp[same[a[i]][j]] < maxx + s[same[a[i]][j]] - s[i - 1]:dp[same[a[i]][j]] = maxx + s[same[a[i]][j]] - s[i - 1]same[a[i]].pop(0)if dp[len(a) - 1] > maxx:maxx = dp[len(a) - 1]return maxx總結(jié)
以上是生活随笔為你收集整理的[Hulu] 数组最大价值的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 【经典】zheng项目搭建
- 下一篇: 北斗卫星轨道有哪些?