国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

[Algo] Maximum Expression Value 表達(dá)式最大值

why_rookie / 2768人閱讀

摘要:給定一個(gè)整數(shù)數(shù)組,要求在數(shù)字之間任意添加乘號(hào),加號(hào)和括號(hào),使得最后表達(dá)式結(jié)果最大。這時(shí)最大值,更新。而本題中可以有和負(fù)數(shù),所以我們要把最大表先初始化為負(fù)最大值,最小表初始化為正最小值。

Maximum Expression Value I

給定一個(gè)整數(shù)數(shù)組,要求在數(shù)字之間任意添加乘號(hào),加號(hào)和括號(hào),使得最后表達(dá)式結(jié)果最大。比如1121,最大值為(1+1)*(2+1),所有數(shù)字都是正數(shù)。

動(dòng)態(tài)規(guī)劃 復(fù)雜度

時(shí)間O(n^2) 空間O(N^2)

思路

先假設(shè)沒(méi)有乘號(hào),那最大值就是所有數(shù)加起來(lái),然后我們考慮將其分段加入乘號(hào),如果某一段是加號(hào),和其他段相乘,那我們就認(rèn)為那段加號(hào)的就被加了個(gè)括號(hào)。所以我們分段的過(guò)程其實(shí)就加了括號(hào)了。但是這么多數(shù)字我們可以分很多不同段,如果用搜索的話難免會(huì)有重復(fù)計(jì)算,所以這里用到動(dòng)態(tài)規(guī)劃,假設(shè)dp[i][j]表示總長(zhǎng)為i的一段數(shù)字,其中前j長(zhǎng)的哪一段中可以包含乘號(hào),所能產(chǎn)生的最大值,這么一來(lái),假設(shè)題目所給的數(shù)字有n個(gè),那dp[n][n]就是這所有的數(shù)字組合起來(lái)既有加號(hào)又有乘號(hào)的式子的最大值了。再假設(shè)sum(k, i)表示所給數(shù)字從第k個(gè)到第i個(gè)數(shù)字的和。遞推式為dp[i][j] = max(dp[i][j], dp[k][j - 1] * sum(k + 1, i)),這里i >= k >= j。其中后半部分dp[k][j - 1] * sum(k + 1, i)表示,我們把總長(zhǎng)為i的數(shù)字分割成前k個(gè),和k + 1到最后兩部分。前半部分最大值已知,我們用它來(lái)乘以后半部分的和,用這種方法來(lái)決定哪一段只用加號(hào)。
舉例說(shuō)明,假設(shè)所給數(shù)字為

3 2 6

我們可以有最大值3 * 2 * 6 = 36,一開始我們有:

sum: 3 5 11
          j=0  j=1  j=2  j=3
dp:  i=0  0    0    0    0
     i=1  0    3    0    0
     i=2  0    5    0    0
     i=3  0    11   0    0

由于總長(zhǎng)為i,其中前1位數(shù)字可以包含乘號(hào)的情況,就是所有數(shù)字都不包含乘號(hào),所以最大值就是累加值。然后我們看總長(zhǎng)為2開始(總長(zhǎng)為1就是第一個(gè)數(shù),沒(méi)有計(jì)算的必要),前2位數(shù)字可以包含乘號(hào)的情況,這里我們可以有分割點(diǎn)k = 1時(shí),是3 + 2 = 5k = 2時(shí)是3 * 2 = 6兩種情況(k表示從第k位開始只有加號(hào))。這時(shí)最大值6,更新dp[2][2]

          j=0  j=1  j=2  j=3
dp:  i=0  0    0    0    0
     i=1  0    3    0    0
     i=2  0    5    6    0
     i=3  0    11   0    0

然后我們看總長(zhǎng)為3開始(總長(zhǎng)為1就是第一個(gè)數(shù),沒(méi)有計(jì)算的必要),前2位數(shù)字可以包含乘號(hào)的情況。這里k=2時(shí),3 * (2 + 6) = 24, k=3時(shí),6 * 6 = 36(第一個(gè)6是dp[2][2],第二個(gè)6是我們所給數(shù)字中的6)

          j=0  j=1  j=2  j=3
dp:  i=0  0    0    0    0
     i=1  0    3    0    0
     i=2  0    5    6    0
     i=3  0    11   24   36

更新完dp[3][3]我們也就計(jì)算完所有情況了,這時(shí)可知最大值是36.

注意

全局最大max在第一個(gè)用于累加的for循環(huán)后,要置為dp[n][0],否則我們會(huì)把全部數(shù)字加起來(lái)這個(gè)組合給漏掉。

代碼
public class MaxValueAddingOperator {
    public int solve(int[] nums){
        int n = nums.length;
        int[] sum = new int[n + 1];
        int[][] dp = new int[n + 1][n + 1];
        // 初始化累加數(shù)組,還有不用乘號(hào)的情況
        for(int idx = 1; idx <= n; idx++){
            sum[idx] = sum[idx - 1] + nums[idx - 1];
            dp[idx][1] = sum[idx];
        }
        int max = dp[n][0];
        // 對(duì)于總長(zhǎng)為numOfDigitsInTotal的數(shù)字序列
        for(int numOfDigitsInTotal = 2; numOfDigitsInTotal <= n; numOfDigitsInTotal++){
            // 前numOfDigitsWithMult個(gè)數(shù)字可以包含乘號(hào)來(lái)計(jì)算的話
            for(int numOfDigitsWithMult = 2; numOfDigitsWithMult <= numOfDigitsInTotal; numOfDigitsWithMult++){
                // 從splitPointBetweenAddAndMult開始只用加號(hào)的話,求最大值
                for(int splitPointBetweenAddAndMult = numOfDigitsWithMult; splitPointBetweenAddAndMult <= numOfDigitsInTotal; splitPointBetweenAddAndMult++){
                    dp[numOfDigitsInTotal][numOfDigitsWithMult] = Math.max(dp[numOfDigitsInTotal][numOfDigitsWithMult],
                            dp[splitPointBetweenAddAndMult - 1][numOfDigitsWithMult - 1] * (sum[numOfDigitsInTotal] - sum[splitPointBetweenAddAndMult - 1]));
                }
                if(numOfDigitsInTotal == n && dp[n][numOfDigitsWithMult] > max){
                    max = dp[n][numOfDigitsWithMult];
                }
            }
        }
        return max;
    }
    
    public static void main(String[] args){
        MaxValueAddingOperator mvao = new MaxValueAddingOperator();
        int[] arr = {3, 2, 6};
        int[] arr2 = {1, 1, 2, 1};
        System.out.println(mvao.solve(arr));
        System.out.println(mvao.solve(arr2));
    }
}
Maximum Expression Value II

給定一個(gè)整數(shù)數(shù)組,要求在數(shù)字之間任意添加乘號(hào),加號(hào)和括號(hào),使得最后表達(dá)式結(jié)果最大。比如1121,最大值為(1+1)*(2+1),這里數(shù)字可以是0或者負(fù)數(shù)。

動(dòng)態(tài)規(guī)劃 復(fù)雜度

時(shí)間O(n^2) 空間O(N^2)

思路

解法和I是一樣的,不過(guò)這里我們要維護(hù)一個(gè)最大表和一個(gè)最小表,這樣,每次我們要乘的那個(gè)數(shù)是正數(shù)時(shí),我們的最大值就是之前的最大值乘以這個(gè)正數(shù),最小值就是之前的最小值乘以這個(gè)正數(shù)。如果要乘的是個(gè)負(fù)數(shù)的話,我們的最大值就是之前的最小值乘以這個(gè)正數(shù),最小值就是之前的最大值乘以這個(gè)正數(shù)。另外,我們還要先初始化這個(gè)兩個(gè)表,因?yàn)橹澳穷}結(jié)果肯定大于0,所以我們不用初始化,不管怎么算原先矩陣中的0都會(huì)被替換掉。而本題中可以有0和負(fù)數(shù),所以我們要把最大表先初始化為負(fù)最大值,最小表初始化為正最小值。

代碼
public int solve2(int[] nums){
    int n = nums.length;
    int[] sum = new int[n + 1];
    int[][] dpMax = new int[n + 1][n + 1];
    int[][] dpMin = new int[n + 1][n + 1];
    // 初始化最大表最小表
    for(int idx1 = 1; idx1 <=n; idx1++){
        for(int idx2 = 1; idx2 <=n; idx2++){
            dpMax[idx1][idx2] = Integer.MIN_VALUE;
        }
    }
    for(int idx1 = 1; idx1 <=n; idx1++){
        for(int idx2 = 1; idx2 <=n; idx2++){
            dpMin[idx1][idx2] = Integer.MAX_VALUE;
        }
    }
    // 初始化累加表
    for(int idx = 1; idx <= n; idx++){
        sum[idx] = sum[idx - 1] + nums[idx - 1];
        dpMax[idx][1] = sum[idx];
        dpMin[idx][1] = sum[idx];
    }
    int max = dpMax[n][1];
    for(int numOfDigitsInTotal = 2; numOfDigitsInTotal <= n; numOfDigitsInTotal++){
        for(int numOfDigitsWithMult = 2; numOfDigitsWithMult <= numOfDigitsInTotal; numOfDigitsWithMult++){
            for(int splitPointBetweenAddAndMult = numOfDigitsWithMult; splitPointBetweenAddAndMult <= numOfDigitsInTotal; splitPointBetweenAddAndMult++){
                int partialSum = sum[numOfDigitsInTotal] - sum[splitPointBetweenAddAndMult - 1];
                // 根據(jù)待會(huì)要乘的數(shù)的正負(fù)號(hào),來(lái)判斷我們乘的對(duì)象是最大表還是最小表
                if(partialSum < 0){
                    dpMax[numOfDigitsInTotal][numOfDigitsWithMult] = Math.max(dpMax[numOfDigitsInTotal][numOfDigitsWithMult],
                            dpMin[splitPointBetweenAddAndMult - 1][numOfDigitsWithMult - 1] * partialSum);
                    dpMin[numOfDigitsInTotal][numOfDigitsWithMult] = Math.min(dpMin[numOfDigitsInTotal][numOfDigitsWithMult],
                            dpMax[splitPointBetweenAddAndMult - 1][numOfDigitsWithMult - 1] * partialSum);
                } else {
                    dpMax[numOfDigitsInTotal][numOfDigitsWithMult] = Math.max(dpMax[numOfDigitsInTotal][numOfDigitsWithMult],
                            dpMax[splitPointBetweenAddAndMult - 1][numOfDigitsWithMult - 1] * partialSum);
                    dpMin[numOfDigitsInTotal][numOfDigitsWithMult] = Math.min(dpMin[numOfDigitsInTotal][numOfDigitsWithMult],
                            dpMin[splitPointBetweenAddAndMult - 1][numOfDigitsWithMult - 1] * partialSum);
                }
            }
            if(numOfDigitsInTotal == n && dpMax[n][numOfDigitsWithMult] > max){
                max = dpMax[n][numOfDigitsWithMult];
            }
        }
    }
    return max;
}
后續(xù) Follow Up

Q:如果輸入是double數(shù)組怎么辦?
A: 一樣的做法,用第二題的解肯定沒(méi)問(wèn)題。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/66181.html

相關(guān)文章

  • python learn 01 basic

    摘要:輸入的模塊上使用。我們看到它包含一個(gè)龐大的屬性列表。默認(rèn)地,它返回當(dāng)前模塊的屬性列表。 Python Learn Part More_Info Content List 1.Python Introduce 1.1 python REPL 1.2 python helloworld.py 1.3 python help() 1.4 to python_string 1.5 dif...

    MageekChiu 評(píng)論0 收藏0
  • template7入門教程及對(duì)它的一些看法

    摘要:是的內(nèi)置模板引擎,在此之前使用過(guò),不過(guò)剛剛打開看了下,已經(jīng)停止更新,并且將要被所替代。如果需要進(jìn)行一些條件判斷,則使用。我們就主要說(shuō)一下不常用的或者其他模板引擎里沒(méi)有的一些功能。 template7是framework7的內(nèi)置模板引擎,在此之前使用過(guò)jquery-tmpl,不過(guò)剛剛打開github看了下,已經(jīng)停止更新,并且將要被JsRender所替代。妹的,JsRender又是什么鬼啊...

    Developer 評(píng)論0 收藏0
  • template7入門教程及對(duì)它的一些看法

    摘要:是的內(nèi)置模板引擎,在此之前使用過(guò),不過(guò)剛剛打開看了下,已經(jīng)停止更新,并且將要被所替代。如果需要進(jìn)行一些條件判斷,則使用。我們就主要說(shuō)一下不常用的或者其他模板引擎里沒(méi)有的一些功能。 template7是framework7的內(nèi)置模板引擎,在此之前使用過(guò)jquery-tmpl,不過(guò)剛剛打開github看了下,已經(jīng)停止更新,并且將要被JsRender所替代。妹的,JsRender又是什么鬼啊...

    kaka 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<