zoukankan      html  css  js  c++  java
  • [LeetCode 1420] Build Array Where You Can Find The Maximum Exactly K Comparisons

    Given three integers nm and k. Consider the following algorithm to find the maximum element of an array of positive integers:

    You should build the array arr which has the following properties:

    • arr has exactly n integers.
    • 1 <= arr[i] <= m where (0 <= i < n).
    • After applying the mentioned algorithm to arr, the value search_cost is equal to k.

    Return the number of ways to build the array arr under the mentioned conditions. As the answer may grow large, the answer must be computed modulo 10^9 + 7.

     

    Example 1:

    Input: n = 2, m = 3, k = 1
    Output: 6
    Explanation: The possible arrays are [1, 1], [2, 1], [2, 2], [3, 1], [3, 2] [3, 3]
    

    Example 2:

    Input: n = 5, m = 2, k = 3
    Output: 0
    Explanation: There are no possible arrays that satisify the mentioned conditions.
    

    Example 3:

    Input: n = 9, m = 1, k = 1
    Output: 1
    Explanation: The only possible array is [1, 1, 1, 1, 1, 1, 1, 1, 1]
    

    Example 4:

    Input: n = 50, m = 100, k = 25
    Output: 34549172
    Explanation: Don't forget to compute the answer modulo 1000000007
    

    Example 5:

    Input: n = 37, m = 17, k = 7
    Output: 418930126
    

     

    Constraints:

    • 1 <= n <= 50
    • 1 <= m <= 100
    • 0 <= k <= n

    O(N * K * M^2) dynamic programming

    State:

    dp[i][j][maxV]: the number of ways to build an array of arr[0, i] (length i + 1), with j search costs and max number of maxV. 

    Transition:

    1. if the current value V is not a new max number, then V must be in range [1, maxV], otherwise V will be a new max number. So the current number has maxV different choices, each choice corresponds to the number of ways of shorter length by 1, same search cost and max number, dp[i - 1][j][maxV]. So dp[i][j][maxV] += dp[i - 1][j][maxV] * maxV;  

    2. if the current value V is a new max number, then V only has one option, maxV. We can append maxV to all arrays of shorter length by 1, smaller search cost by 1 and max value smaller than maxV to get array of longer length by 1, bigger search cost by 1 and max number maxV. So dp[i][j][maxV] = Sum of (dp[i - 1][j - 1][smallerV]), smallerV in [1, maxV - 1].

    Init:

    For array of 1 element, there is 1 way for each different number choice with a search cost of 1. This is true because maximum value is initially set to < 0, so any number choice will incur an update.  dp[0][1][maxV] = 1, maxV in [1, m].

    Answer: Sum of dp[n - 1][k][maxV], maxV in [1, m]. For each valid array, its max value must be in [1, m], so the final answer is the sum over all max value possibilities for length n and search cost k.

    class Solution {
        public int numOfArrays(int n, int m, int k) {
            int mod = (int)1e9 + 7;
            long[][][] dp = new long[n][k + 1][m + 1];
            for(int maxV = 1; maxV <= m; maxV++) {
                dp[0][1][maxV] = 1;
            }
            for(int i = 1; i < n; i++) {
                for(int j = 1; j <= k; j++) {
                    for(int maxV = 1; maxV <= m; maxV++) {
                        //newly added number is not a new max value
                        dp[i][j][maxV] = (dp[i][j][maxV] + dp[i - 1][j][maxV] * maxV) % mod;
                        //newly added number is a new max value
                        for(int smallerV = 1; smallerV < maxV; smallerV++) {
                            dp[i][j][maxV] = (dp[i][j][maxV] + dp[i - 1][j - 1][smallerV]) % mod;
                        }
                    }
                }
            }
            long ans = 0;
            for(int v = 1; v <= m; v++) {
                ans = (ans + dp[n - 1][k][v]) % mod;
            }
            return (int)ans;
        }
    }

    The for loop to for case: newly added number is a new max value does redundant work as it sums up the same prefixes dp[i - 1][j - 1][smallerV] repeatly. To optimize this, we can create a prefix sum array to save the previous summation results. This reduces the runtime of computing newly added number is a new max value case from O(M) to O(1). 

    class Solution {
        public int numOfArrays(int n, int m, int k) {
            int mod = (int)1e9 + 7;
            long[][][] dp = new long[n][k + 1][m + 1];
            long[][][] ps = new long[n][k + 1][m + 1];
            for(int maxV = 1; maxV <= m; maxV++) {
                dp[0][1][maxV] = 1;
                ps[0][1][maxV] = ps[0][1][maxV - 1] + 1;
            }
            for(int i = 1; i < n; i++) {
                for(int j = 1; j <= k; j++) {
                    for(int maxV = 1; maxV <= m; maxV++) {
                        //newly added number is not a new max value
                        dp[i][j][maxV] = (dp[i][j][maxV] + dp[i - 1][j][maxV] * maxV) % mod;
                        //newly added number is a new max value
                        dp[i][j][maxV] = (dp[i][j][maxV] + ps[i - 1][j - 1][maxV - 1]) % mod;
                        ps[i][j][maxV] = (ps[i][j][maxV - 1] + dp[i][j][maxV]) % mod;
                    }
                }
            }
            long ans = 0;
            for(int v = 1; v <= m; v++) {
                ans = (ans + dp[n - 1][k][v]) % mod;
            }
            return (int)ans;
        }
    }
  • 相关阅读:
    4种方法帮你解决IntelliJ IDEA控制台中文乱码问题
    万字长文:解读区块链7类共识算法
    CoralCache:一个提高微服务可用性的中间件
    探究Python源码,终于弄懂了字符串驻留技术
    OAuth:每次授权暗中保护你的那个“MAN”
    厉害了!这群95后正在用三维成像技术让科幻变成现实
    华为云FusionInsight MRS在金融行业存算分离的实践
    【新春特辑】发压岁钱、看贺岁片、AI写春联……华为云社区给大家拜年了
    Java实现 蓝桥杯 算法训练 天数计算
    WebRTC框架中的硬件加速
  • 原文地址:https://www.cnblogs.com/lz87/p/12742029.html
Copyright © 2011-2022 走看看