给定一个数组和一个整数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个要素,要么不选择一个要素,然后计算每个要素的最低成本。
现在,使用一个3D DP数组存储我们的最小成本值,其中cache [i] [prev] [cnt]存储直到第i个元素,prev元素和到目前为止所考虑的数量计数的最小成本。
涉及3个基本条件:
- 如果计算了k个元素,则返回0。
- 如果已遍历数组的所有元素,则返回MAX_VALUE。
- 检查它是否已经在dp数组中计算了。
现在是选择ith元素或不选择ith元素的部分:
- 当不考虑第ith个元素时ans = dp(i + 1,prev,cnt,s,c)
- 当第ith个元素大于上一个元素时,检查添加其成本是否使总成本最小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 elemnets 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 elemnets 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