给定两个由N 个正整数组成的数组A[]和B[]以及成本C 。我们可以从给定数组的每个索引中选择任何一个元素,即,对于任何索引i,我们只能选择元素A[i]或B[i] 。任务是找到从给定的两个数组中选择N 个元素的最小总和,如果我们在下一次迭代中选择从A[]到B[] 中的任何元素,反之亦然,那么成本C也被添加到和。
注意:按索引升序选择元素,即0 ≤ i < N 。
例子:
Input: N = 9, A[] = {7, 6, 18, 6, 16, 18, 1, 17, 17}, B[] = {6, 9, 3, 10, 9, 1, 10, 1, 5}, C = 2
Output: 49
Explanation:
On taking the 1st element from array A, sum = 7
On taking the 2nd element from array A, sum = 7 + 6 = 13
On taking the 3rd element from array B, as we are entering from array A to array B, sum = 13 + 3 + 2 = 18
On taking the 4th element from array A, as we are entering from array B to array A, sum = 18 + 6 + 2 = 26
On taking the 5th element from array B, as we are entering from array A to array B, sum = 26 + 9 + 2 = 37
On taking the 6th element form array B, sum = 37 + 1 = 38
On taking the 7th element from array A, as we are entering from array B to array A, sum = 38 + 1 + 2 = 41
On taking the 8th element form array B, as we are entering from array A to array B, sum = 41 + 1 + 2 = 44
On taking the 9th element from array B, sum = 44 + 5 = 49.
Input: N = 9, A = {3, 2, 3, 1, 3, 3, 1, 4, 1}, B = {1, 2, 3, 4, 4, 1, 2, 1, 3}, C = 1
Output: 18
Explanation:
On taking the 1st element from array B, sum = 1
On taking the 2nd element from array A, sum = 1 + 2 = 3
On taking the 3rd element from array A, sum = 3 + 3 = 6
On taking the 4th element from array A, sum = 6 + 1 = 7
On taking the 5th element from array A, sum = 7 + 3 = 10
On taking the 6th element form array B, as we are entering from array A to array B, sum = 10 + 1 + 1 = 12
On taking the 7th element from array A, as we are entering from array B to array A, sum = 12 + 1 + 1 = 14
On taking the 8th element form array B, as we are entering from array A to array B, sum = 14 + 1 + 1 = 16
On taking the 9th element from array A, as we are entering from array B to array A, sum = 16 + 1 + 1 = 18.
方法:我们将使用动态规划来解决这个问题。以下是步骤:
- 创建N行两列的二维数组dp[][]并将 dp 的所有元素初始化为无穷大。
- 从两个数组中添加元素可能有 4 种可能的情况:
- 当先前添加的元素来自数组 a[] 时,添加来自数组 a[] 的元素。
- 当先前添加的元素来自数组 b[] 时,从数组 a[] 添加一个元素。在这种情况下,将整数 C 与结果相加会带来惩罚。
- 当先前添加的元素来自数组 b[] 时,添加数组 b[] 中的元素。
- 当先前添加的元素来自数组 a[] 时,从数组 b[] 添加一个元素。在这种情况下,将整数 C 与结果相加会带来惩罚。
- 每次更新dp数组,取上述四个条件中的最小值。
- dp[n-1][0]和dp[n-1][1]的最小值是选择N 个元素的最小总和。
下面是上述方法的实现:
C++
// C++ program for the above approach
#include
using namespace std;
// Function that prints minimum sum
// after selecting N elements
void minimumSum(int a[], int b[],
int c, int n)
{
// Initialise the dp array
vector > dp(n,
vector(2,
1e6));
// Base Case
dp[0][0] = a[0];
dp[0][1] = b[0];
for (int i = 1; i < n; i++) {
// Adding the element of array a if
// previous element is also from array a
dp[i][0] = min(dp[i][0],
dp[i - 1][0] + a[i]);
// Adding the element of array a if
// previous element is from array b
dp[i][0] = min(dp[i][0],
dp[i - 1][1] + a[i] + c);
// Adding the element of array b if
// previous element is from array a
// with an extra penalty of integer C
dp[i][1] = min(dp[i][1],
dp[i - 1][0] + b[i] + c);
// Adding the element of array b if
// previous element is also from array b
dp[i][1] = min(dp[i][1],
dp[i - 1][1] + b[i]);
}
// Print the minimum sum
cout << min(dp[n - 1][0],
dp[n - 1][1])
<< "\n";
}
// Driver Code
int main()
{
// Given array arr1[] and arr2[]
int arr1[] = { 7, 6, 18, 6, 16,
18, 1, 17, 17 };
int arr2[] = { 6, 9, 3, 10, 9,
1, 10, 1, 5 };
// Given cost
int C = 2;
int N = sizeof(arr1) / sizeof(arr1[0]);
// Function Call
minimumSum(arr1, arr2, C, N);
return 0;
}
Java
// Java program for the above approach
import java.util.*;
class GFG{
// Function that prints minimum sum
// after selecting N elements
static void minimumSum(int a[], int b[],
int c, int n)
{
// Initialise the dp array
int [][]dp = new int[n][2];
for(int i = 0; i < n; i++)
{
for(int j = 0; j < 2; j++)
{
dp[i][j] = (int) 1e6;
}
}
// Base Case
dp[0][0] = a[0];
dp[0][1] = b[0];
for(int i = 1; i < n; i++)
{
// Adding the element of array a if
// previous element is also from array a
dp[i][0] = Math.min(dp[i][0],
dp[i - 1][0] + a[i]);
// Adding the element of array a if
// previous element is from array b
dp[i][0] = Math.min(dp[i][0],
dp[i - 1][1] + a[i] + c);
// Adding the element of array b if
// previous element is from array a
// with an extra penalty of integer C
dp[i][1] = Math.min(dp[i][1],
dp[i - 1][0] + b[i] + c);
// Adding the element of array b if
// previous element is also from array b
dp[i][1] = Math.min(dp[i][1],
dp[i - 1][1] + b[i]);
}
// Print the minimum sum
System.out.print(Math.min(dp[n - 1][0],
dp[n - 1][1]) + "\n");
}
// Driver Code
public static void main(String[] args)
{
// Given array arr1[] and arr2[]
int arr1[] = { 7, 6, 18, 6, 16,
18, 1, 17, 17 };
int arr2[] = { 6, 9, 3, 10, 9,
1, 10, 1, 5 };
// Given cost
int C = 2;
int N = arr1.length;
// Function call
minimumSum(arr1, arr2, C, N);
}
}
// This code is contributed by gauravrajput1
Python3
# Python3 program for the above approach
# Function that prints minimum sum
# after selecting N elements
def minimumSum(a, b, c, n):
# Initialise the dp array
dp = [[1e6 for i in range(2)]
for j in range(n)]
# Base Case
dp[0][0] = a[0]
dp[0][1] = b[0]
for i in range(1, n):
# Adding the element of array a if
# previous element is also from array a
dp[i][0] = min(dp[i][0],
dp[i - 1][0] + a[i])
# Adding the element of array a if
# previous element is from array b
dp[i][0] = min(dp[i][0],
dp[i - 1][1] + a[i] + c)
# Adding the element of array b if
# previous element is from array a
# with an extra penalty of integer C
dp[i][1] = min(dp[i][1],
dp[i - 1][0] + b[i] + c)
# Adding the element of array b if
# previous element is also from array b
dp[i][1] = min(dp[i][1],
dp[i - 1][1] + b[i])
# Print the minimum sum
print(min(dp[n - 1][0], dp[n - 1][1]))
# Driver code
if __name__ == '__main__':
# Given array arr[]
arr1 = [ 7, 6, 18, 6, 16,
18, 1, 17, 17 ]
arr2 = [ 6, 9, 3, 10, 9,
1, 10, 1, 5 ]
# Given cost
C = 2
N = len(arr1)
# Function Call
minimumSum(arr1, arr2, C, N)
# This code is contributed by Shivam Singh
C#
// C# program for the above approach
using System;
class GFG{
// Function that prints minimum sum
// after selecting N elements
static void minimumSum(int []a, int []b,
int c, int n)
{
// Initialise the dp array
int [,]dp = new int[n, 2];
for(int i = 0; i < n; i++)
{
for(int j = 0; j < 2; j++)
{
dp[i, j] = (int)1e6;
}
}
// Base Case
dp[0, 0] = a[0];
dp[0, 1] = b[0];
for(int i = 1; i < n; i++)
{
// Adding the element of array a if
// previous element is also from array a
dp[i, 0] = Math.Min(dp[i, 0],
dp[i - 1, 0] + a[i]);
// Adding the element of array a if
// previous element is from array b
dp[i, 0] = Math.Min(dp[i, 0],
dp[i - 1, 1] + a[i] + c);
// Adding the element of array b if
// previous element is from array a
// with an extra penalty of integer C
dp[i, 1] = Math.Min(dp[i, 1],
dp[i - 1, 0] + b[i] + c);
// Adding the element of array b if
// previous element is also from array b
dp[i, 1] = Math.Min(dp[i, 1],
dp[i - 1, 1] + b[i]);
}
// Print the minimum sum
Console.Write(Math.Min(dp[n - 1, 0],
dp[n - 1, 1]) + "\n");
}
// Driver Code
public static void Main(String[] args)
{
// Given array arr1[] and arr2[]
int []arr1 = { 7, 6, 18, 6, 16,
18, 1, 17, 17 };
int []arr2 = { 6, 9, 3, 10, 9,
1, 10, 1, 5 };
// Given cost
int C = 2;
int N = arr1.Length;
// Function call
minimumSum(arr1, arr2, C, N);
}
}
// This code is contributed by Rajput-Ji
Javascript
49
时间复杂度: O(N)