zoukankan      html  css  js  c++  java
  • 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

    题意:

      给出一个数组的长度和数组中最大元素的值,以及寻找最大元素的过程中的比较次数,问满足这样要求的数组有多少种?

    思路:

      用动态规划来解决这道题,ways[i][j][k]表示数组长度为i,最大元素为j, 查找最大元素的过程中的比较次数。初始化的时候应该将ways[1][j][1] = 1;

      两个状态转换方程:

      1. ways[i][j][k] = j * ways[i-1][j][k]; //表示在最大值和最大比较次数不变的情况下,数组的长度增加1,状态的数量会增加为原来数量的j倍。这是因为[1 -- j]中的任何一个数字都可以和原来的状态组合而不改变最大值和查找次数。

      2. ways[i][j][k] += ∑(x = 1 to x = j - 1) ways[i-1][x][k-1]; // 表示在数组长度和查找次数都少1的情况下,当最大值比j要小时,都可以在数组中增加一个j,使其长度,最大值和查找的最大次数都改变,从而满足当前状态。

      最后将∑xways[n][x][k] 取余即可。

    Code:

     1 class Solution {
     2     long long ways[55][105][55];
     3     const int mod = 1000000007;
     4 public:
     5     int numOfArrays(int n, int m, int num) {
     6         memset(ways, 0, sizeof(ways));
     7         
     8         for (int j = 1; j <= m; ++j) ways[1][j][1] = 1;
     9         for (int i = 1; i <= n; ++i) {
    10             for (int j = 1; j <= m; ++j) {
    11                 for (int k = 1; k <= num; ++k) {
    12                     long long s = 0;
    13                     s = (j * ways[i-1][j][k]) % mod;
    14                     for (int p = 1; p < j; ++p)
    15                         s = (s + ways[i-1][p][k-1]) % mod;
    16                     ways[i][j][k] = (s + ways[i][j][k]) % mod;
    17                 }
    18             }
    19         }
    20         long long ans = 0;
    21         for (int j = 1; j <= m; ++j) {
    22             ans = (ans + ways[n][j][num]) % mod;
    23         }
    24         return ans;
    25     }
    26 };

    参考:https://leetcode.com/problems/build-array-where-you-can-find-the-maximum-exactly-k-comparisons/discuss/586576/C%2B%2B-Bottom-Up-Dynamic-Programming-with-Explanation

    永远渴望,大智若愚(stay hungry, stay foolish)
  • 相关阅读:
    C#中的正则表达式(1)
    sql link
    Repeater控件绑定数据、分页、数据操作,最佳代码
    存储过程事物
    sql db link string
    存储过程返回值
    net打包
    excel c# 输出
    常用的js验证数字,电话号码,传真,邮箱,手机号码,邮编,日期
    sql 大全
  • 原文地址:https://www.cnblogs.com/h-hkai/p/12757618.html
Copyright © 2011-2022 走看看