📌  相关文章
📜  选择 K 个严格递增元素的最小成本

📅  最后修改于: 2021-09-22 10:21:17             🧑  作者: Mango

给定一个数组和一个整数 K。另外给出一个数组,它存储从第一个数组中选择元素的成本。任务是计算从数组中选择 K 个严格递增元素的最小成本。
例子:

Input: N = 4, K = 2
ele[] = {2, 6, 4, 8}
cost[] = {40, 20, 30, 10}
Output: 30
Explanation:
30 is the minimum cost by selecting elements 
6 and 8 from the array with cost 
10 + 20 respectively

Input: N = 11, K = 4
ele = {2, 6, 4, 8, 1, 3, 15, 9, 22, 16, 45}
cost = {40, 20, 30, 10, 50, 10, 20, 30, 40, 20, 10}
Output: 60
Explanation:
60 is the minimum cost by selecting elements 
3, 15, 16, 45 from the array with cost 
10 + 20 + 20 + 10 respectively

方法:
使用动态规划方法可以轻松解决给定的问题。由于问题要求增加元素然后最小成本,因此很明显我们必须通过选择第 i 个元素或不选择第 i 个元素来移动,并计算每个元素的最小成本。
现在,取一个 3D DP 数组,它存储我们的最小成本值,其中 cache[i][prev][cnt] 存储直到第 i 个元素、prev 元素和迄今为止考虑的数字计数的最小成本。
涉及3个基本条件:

  • 如果计算 k 个元素,则返回 0。
  • 如果已遍历数组的所有元素,则返回 MAX_VALUE。
  • 检查它是否已经在 dp 数组中计算过。

现在是选择第 i 个元素或不选择第 i 个元素的部分:

  • 当第 i 个元素不被考虑时 ans = dp(i+1, prev, cnt, s, c)
  • 当第 i 个元素大于前一个元素时,检查添加其成本是否使总成本最小 ans = min(ans, c[i] + dp(i+1, i, cnt+1, s, c))

下面是上述方法的实现:

CPP
// C++ program for
// the above approach
#include 
using namespace std;
 
const int N = 1005;
const int K = 20;
int n, k;
int dp[N + 1][N + 1][K + 1];
 
// Function to calculate
// min cost to choose
// k increasing elements
int minCost(int i, int prev, int cnt,
                    int ele[], int cost[])
{
    // If k elements are
    // counted return 0
    if (cnt == k + 1) {
        return 0;
    }
 
    // If all elements
    // of array has been
    // traversed then
    // return MAX_VALUE
    if (i == n + 1) {
        return 1e5;
    }
 
    // To check if this is
    // already calculated
    int& ans = dp[i][prev][cnt];
    if (ans != -1) {
        return ans;
    }
 
    // When i'th elements
    // is not considered
    ans = minCost(i + 1, prev, cnt, ele, cost);
 
    // When the ith element
    // is greater than previous
    // element check if adding
    // its cost makes total cost minimum
    if (ele[i] > ele[prev]) {
        ans = min(ans, cost[i] + minCost(i + 1,
                           i, cnt + 1, ele, cost));
    }
    return ans;
}
 
// Driver code
int main()
{
 
    memset(dp, -1, sizeof(dp));
    n = 4;
    k = 2;
 
    int ele[n + 1] = { 0, 2, 6, 4, 8 };
 
    int cost[n + 1] = { 0, 40, 20, 30, 10 };
 
    int ans = minCost(1, 0, 1, ele, cost);
 
    if (ans == 1e5) {
        ans = -1;
    }
 
    cout << ans << endl;
 
    return 0;
}


Python3
# Python3 program for
# the above approach
N = 1005;
K = 20;
 
n = 0
k = 0
 
dp = [[[-1 for k in range(K + 1)] for j in range(N + 1)] for i in range(N + 1)]
  
# Function to calculate
# min cost to choose
# k increasing elements
def minCost(i, prev, cnt, ele, cost):
 
    # If k elements are
    # counted return 0
    if (cnt == k + 1):
        return 0;
      
    # If all elements
    # of array has been
    # traversed then
    # return MAX_VALUE
    if (i == n + 1):
        return 100000;
     
    # To check if this is
    # already calculated
    ans = dp[i][prev][cnt];
     
    if (ans != -1):
        return ans;
     
    # When i'th elements
    # is not considered
    ans = minCost(i + 1, prev, cnt, ele, cost);
  
    # When the ith element
    # is greater than previous
    # element check if adding
    # its cost makes total cost minimum
    if (ele[i] > ele[prev]):
        ans = min(ans, cost[i] + minCost(i + 1, i, cnt + 1, ele, cost));
     
    return ans;
 
# Driver code
if __name__=='__main__':
  
    n = 4;
    k = 2;
  
    ele = [ 0, 2, 6, 4, 8 ]
  
    cost = [ 0, 40, 20, 30, 10 ]
  
    ans = minCost(1, 0, 1, ele, cost);
  
    if (ans == 100000):
        ans = -1;
     
    print(ans)
  
# This code is contributed by rutvik_56


输出:
30

如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程学生竞争性编程现场课程。