给定一个数组和一个整数 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 现场工作专业课程和学生竞争性编程现场课程。