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)
  • 相关阅读:
    maven
    Web开发入门
    网络编程之Socket
    自定义注解与设计模式
    数据交换格式与SpringIOC底层实现
    caffe笔记之例程学习(二)
    caffe笔记之例程学习
    ubuntu14.04 caffe环境配置
    Pattern Recognition (Fourth Edition)读书笔记之mvnrnd函数
    MIF文件编写小技巧
  • 原文地址:https://www.cnblogs.com/h-hkai/p/12757618.html
Copyright © 2011-2022 走看看