给定正整数的数组arr []。任务是从数组中找到最小总和子序列,以便在四个连续元素的所有组中选取至少一个值。
例子 :
Input: arr[] = {1, 2, 3, 4, 5, 6, 7, 8}
Output: 6
6 is sum of output subsequence {1, 5}
Note that we have following subarrays of four
consecutive elements
{(1, 2, 3, 4),
(2, 3, 4, 5),
(3, 4, 5, 6)
(4, 5, 6, 7)
(5, 6, 7, 8)}
Our subsequence {1, 5} has an element from
all above groups of four consecutive elements.
And this subsequence is minimum sum such
subsequence.
Input : arr[] = {1, 2, 3, 3, 4, 5, 6, 1}
Output : 4
The subsequence is {3, 1}. Here we consider
second three.
Input: arr[] = {1, 2, 3, 2, 1}
Output: 2
The subsequence can be {1, 1} or {2}
Input: arr[] = {6, 7, 8}
Output: 6
Input: arr[] = {6, 7}
Output: 6
这个想法类似于LIS问题。我们存储以arr []的每个元素结尾的最小和子序列。最后,我们返回最后四个值中的最小值。
dp[i] stores minimum sum subsequence (with at least
one of every four consecutive elements) of arr[0..i]
such that arr[i] is part of the solution. Note that
this may not be the best solution for subarray
arr[0..i].
We can recursively compute dp[i] using below formula
dp[i] = arr[i] + min(dp[i-1], dp[i-2], dp[i-3], dp[i-4])
Finally we return minimum of dp[n-1], dp[n-2],
dp[n-4] and dp[n-3]
以下是上述想法的实现。
C++
// C++ program to find minimum sum subsequence
// of an array such that one of every four
// consecutive elements is picked.
#include
using namespace std;
// Returns sum of minimum sum subsequence
// such that one of every four consecutive
// elements is picked from arr[].
int minSum(int arr[], int n)
{
// dp[i] is going to store minimum sum
// subsequence of arr[0..i] such that arr[i]
// is part of the solution. Note that this
// may not be the best solution for subarray
// arr[0..i]
int dp[n];
// If there is single value, we get the
// minimum sum equal to arr[0]
if (n == 1)
return arr[0];
// If there are two values, we get the
// minimum sum equal to the minimum of
// two values
if (n == 2)
return min(arr[0], arr[1]);
// If there are three values, return
// minimum of the three elements of
// array
if (n == 3)
return min(arr[0], min(arr[1], arr[2]));
// If there are four values, return minimum
// of the four elements of array
if (n == 4)
return min(min(arr[0], arr[1]),
min(arr[2], arr[3]));
dp[0] = arr[0];
dp[1] = arr[1];
dp[2] = arr[2];
dp[3] = arr[3];
for (int i = 4; i < n; i++)
dp[i] = arr[i] + min(min(dp[i - 1], dp[i - 2]),
min(dp[i - 3], dp[i - 4]));
// Return the minimum of last 4 index
return min(min(dp[n - 1], dp[n - 2]),
min(dp[n - 4], dp[n - 3]));
}
// Driver code
int main()
{
int arr[] = { 1, 2, 3, 3, 4, 5, 6, 1 };
int n = sizeof(arr) / sizeof(arr[0]);
cout << minSum(arr, n);
return 0;
}
Java
// Java program to find minimum sum subsequence
// of an array such that one of every four
// consecutive elements is picked.
import java.io.*;
class GFG {
// Returns sum of minimum sum subsequence
// such that one of every four consecutive
// elements is picked from arr[].
static int minSum(int[] arr, int n)
{
// dp[i] is going to store minimum sum
// subsequence of arr[0..i] such that arr[i]
// is part of the solution. Note that this
// may not be the best solution for subarray
// arr[0..i]
int[] dp = new int[n];
// If there is single value, we get the
// minimum sum equal to arr[0]
if (n == 1)
return arr[0];
// If there are two values, we get the
// minimum sum equal to the minimum of
// two values
if (n == 2)
return Math.min(arr[0], arr[1]);
// If there are three values, return
// minimum of the three elements of
// array
if (n == 3)
return Math.min(arr[0], Math.min(arr[1], arr[2]));
// If there are four values, return minimum
// of the four elements of array
if (n == 4)
return Math.min(Math.min(arr[0], arr[1]),
Math.min(arr[2], arr[3]));
dp[0] = arr[0];
dp[1] = arr[1];
dp[2] = arr[2];
dp[3] = arr[3];
for (int i = 4; i < n; i++)
dp[i] = arr[i] + Math.min(Math.min(dp[i - 1], dp[i - 2]),
Math.min(dp[i - 3], dp[i - 4]));
// Return the minimum of last 4 index
return Math.min(Math.min(dp[n - 1], dp[n - 2]),
Math.min(dp[n - 4], dp[n - 3]));
}
// Driver code
static public void main(String[] args)
{
int[] arr = { 1, 2, 3, 3, 4, 5, 6, 1 };
int n = arr.length;
System.out.println(minSum(arr, n));
}
}
// This Code is contributed by vt_m.
Python3
# Python 3 program to find minimum sum
# subsequence of an array such that one
# of every four consecutive elements is picked.
# Returns sum of minimum sum subsequence
# such that one of every four consecutive
# elements is picked from arr[].
def minSum(arr, n):
# dp[i] is going to store minimum sum
# subsequence of arr[0..i] such that
# arr[i] is part of the solution. Note
# that this may not be the best solution
# for subarray arr[0..i]
dp = [0] * n
# If there is single value, we get
# the minimum sum equal to arr[0]
if (n == 1):
return arr[0]
# If there are two values, we get the
# minimum sum equal to the minimum of
# two values
if (n == 2):
return min(arr[0], arr[1])
# If there are three values, return
# minimum of the three elements of
# array
if (n == 3):
return min(arr[0],
min(arr[1], arr[2]))
# If there are four values,
# return minimum of the four
# elements of array
if (n == 4):
return min(min(arr[0], arr[1]),
min(arr[2], arr[3]))
dp[0] = arr[0]
dp[1] = arr[1]
dp[2] = arr[2]
dp[3] = arr[3]
for i in range( 4, n):
dp[i] = arr[i] + min(min(dp[i - 1], dp[i - 2]),
min(dp[i - 3], dp[i - 4]))
# Return the minimum of last 4 index
return min(min(dp[n - 1], dp[n - 2]),
min(dp[n - 4], dp[n - 3]))
# Driver code
if __name__ == "__main__":
arr = [ 1, 2, 3, 3, 4, 5, 6, 1 ]
n = len(arr)
print(minSum(arr, n))
# This code is contributed by ita_c
C#
// C# program to find minimum sum subsequence
// of an array such that one of every four
// consecutive elements is picked.
using System;
class GFG {
// Returns sum of minimum sum subsequence
// such that one of every four consecutive
// elements is picked from arr[].
static int minSum(int[] arr, int n)
{
// dp[i] is going to store minimum sum
// subsequence of arr[0..i] such that arr[i]
// is part of the solution. Note that this
// may not be the best solution for subarray
// arr[0..i]
int[] dp = new int[n];
// If there is single value, we get the
// minimum sum equal to arr[0]
if (n == 1)
return arr[0];
// If there are two values, we get the
// minimum sum equal to the minimum of
// two values
if (n == 2)
return Math.Min(arr[0], arr[1]);
// If there are three values, return
// minimum of the three elements of
// array
if (n == 3)
return Math.Min(arr[0], Math.Min(arr[1], arr[2]));
// If there are four values, return minimum
// of the four elements of array
if (n == 4)
return Math.Min(Math.Min(arr[0], arr[1]),
Math.Min(arr[2], arr[3]));
dp[0] = arr[0];
dp[1] = arr[1];
dp[2] = arr[2];
dp[3] = arr[3];
for (int i = 4; i < n; i++)
dp[i] = arr[i] + Math.Min(Math.Min(dp[i - 1], dp[i - 2]),
Math.Min(dp[i - 3], dp[i - 4]));
// Return the minimum of last 4 index
return Math.Min(Math.Min(dp[n - 1], dp[n - 2]),
Math.Min(dp[n - 4], dp[n - 3]));
}
// Driver code
static public void Main()
{
int[] arr = { 1, 2, 3, 3, 4, 5, 6, 1 };
int n = arr.Length;
Console.WriteLine(minSum(arr, n));
}
}
// This code is contributed by vt_m.
Javascript
C++
// CPP program to calculate
// minimum possible sum for given constraint
#include
typedef long long ll;
using namespace std;
// function to calculate min sum using dp
int minSum(int ar[], int n)
{
// if elements are less than or equal to 4
if (n <= 4)
return *min_element(ar, ar + n);
// save start four element as it is
int sum[n];
sum[0] = ar[0];
sum[1] = ar[1];
sum[2] = ar[2];
sum[3] = ar[3];
// compute sum[] for all rest elements
for (int i = 4; i < n; i++)
sum[i] = ar[i] + (*min_element(sum + i - 4, sum + i));
// Since one of the last 4 elements must be
// present
return *min_element(sum + n - 4, sum + n);
}
// driver program
int main()
{
int ar[] = { 2, 4, 1, 5, 2, 3, 6, 1, 2, 4 };
int n = sizeof(ar) / sizeof(ar[0]);
cout << "Minimum sum = " << minSum(ar, n);
return 0;
}
Java
// Java program to calculate
// minimum possible sum for given constraint
import java.util.Arrays;
class GFG
{
// function to calculate min sum using dp
static int minSum(int ar[], int n)
{
// if elements are less than or equal to 4
if (n <= 4)
return Arrays.stream(ar).min().getAsInt();
// save start four element as it is
int []sum = new int[n];
sum[0] = ar[0];
sum[1] = ar[1];
sum[2] = ar[2];
sum[3] = ar[3];
// compute sum[] for all rest elements
for (int i = 4; i < n; i++)
//sum[i] = ar[i] + (*min_element(sum + i - 4, sum + i));
sum[i] = ar[i] + Arrays.stream(Arrays.copyOfRange(
sum, i - 4, i)).min().getAsInt();
// Since one of the last 4 elements must be
// present
return Arrays.stream(Arrays.copyOfRange(
sum, n - 4, n)).min().getAsInt();
}
// Driver Code
public static void main(String[] args)
{
int ar[] = { 2, 4, 1, 5, 2, 3, 6, 1, 2, 4 };
int n = ar.length;
System.out.println("Minimum sum = " + minSum(ar, n));
}
}
// This code is contributed by PrinciRaj1992
Python3
# Python3 program to calculate
# minimum possible sum for given constraint
# function to calculate min sum using dp
def minSum(ar, n):
# if elements are less than or equal to 4
if (n <= 4):
return min(ar)
# save start four element as it is
sum = [0 for i in range(n)]
sum[0] = ar[0]
sum[1] = ar[1]
sum[2] = ar[2]
sum[3] = ar[3]
# compute sum[] for all rest elements
for i in range(4, n):
sum[i] = ar[i] + min(sum[i - 4:i])
# Since one of the last 4 elements must be
# present
return min(sum[n - 4:n])
# Driver Code
ar = [2, 4, 1, 5, 2, 3, 6, 1, 2, 4]
n = len(ar)
print("Minimum sum = ", minSum(ar, n))
# This code is contributed by Mohit Kumar
C#
// C# program to calculate
// minimum possible sum for given constraint
using System;
using System.Linq;
class GFG
{
// function to calculate min sum using dp
static int minSum(int []ar, int n)
{
// if elements are less than or equal to 4
if (n <= 4)
return ar.Min();
// save start four element as it is
int []sum = new int[n];
sum[0] = ar[0];
sum[1] = ar[1];
sum[2] = ar[2];
sum[3] = ar[3];
int []tempArr;
// compute sum[] for all rest elements
for (int i = 4; i < n; i++)
{
//sum[i] = ar[i] + (*min_element(sum + i - 4, sum + i));
tempArr = new int[4];
Array.Copy(sum, i - 4, tempArr, 0, 4);
sum[i] = ar[i] + tempArr.Min();
}
// Since one of the last 4 elements must be
// present
tempArr = new int[4];
Array.Copy(sum,n-4,tempArr,0,4);
return tempArr.Min();
}
// Driver Code
public static void Main(String[] args)
{
int []ar = { 2, 4, 1, 5, 2, 3, 6, 1, 2, 4 };
int n = ar.Length;
Console.WriteLine("Minimum sum = " +
minSum(ar, n));
}
}
// This code is contributed by Rajput-Ji
输出:
4
替代解决方案:
首先,认为我们只有四个要素,那么我们的结果至少是四个给定的要素。现在,如果我们有四个以上的元素,则必须维护一个数组sum [],其中sum [i]包括直到第i个元素的可能的最小和,并且第i个元素也必须是解决方案的一部分。
在计算sum [i]时,我们的基本条件是arr [i]必须是sum [i]的一部分,然后我们必须有一个来自最后四个元素的元素。因此,我们可以递归计算sum [i]作为arr [i]和最小值(sum [i-1],sum [i-2],sum [i-3],sum [i-4])之和。由于我们的问题的递归结构中存在重叠的子问题,因此可以使用动态编程来解决此问题。对于最终结果,我们必须计算sum []数组的后四个值中的最小值,因为结果必须包含后四个元素中的一个。
C++
// CPP program to calculate
// minimum possible sum for given constraint
#include
typedef long long ll;
using namespace std;
// function to calculate min sum using dp
int minSum(int ar[], int n)
{
// if elements are less than or equal to 4
if (n <= 4)
return *min_element(ar, ar + n);
// save start four element as it is
int sum[n];
sum[0] = ar[0];
sum[1] = ar[1];
sum[2] = ar[2];
sum[3] = ar[3];
// compute sum[] for all rest elements
for (int i = 4; i < n; i++)
sum[i] = ar[i] + (*min_element(sum + i - 4, sum + i));
// Since one of the last 4 elements must be
// present
return *min_element(sum + n - 4, sum + n);
}
// driver program
int main()
{
int ar[] = { 2, 4, 1, 5, 2, 3, 6, 1, 2, 4 };
int n = sizeof(ar) / sizeof(ar[0]);
cout << "Minimum sum = " << minSum(ar, n);
return 0;
}
Java
// Java program to calculate
// minimum possible sum for given constraint
import java.util.Arrays;
class GFG
{
// function to calculate min sum using dp
static int minSum(int ar[], int n)
{
// if elements are less than or equal to 4
if (n <= 4)
return Arrays.stream(ar).min().getAsInt();
// save start four element as it is
int []sum = new int[n];
sum[0] = ar[0];
sum[1] = ar[1];
sum[2] = ar[2];
sum[3] = ar[3];
// compute sum[] for all rest elements
for (int i = 4; i < n; i++)
//sum[i] = ar[i] + (*min_element(sum + i - 4, sum + i));
sum[i] = ar[i] + Arrays.stream(Arrays.copyOfRange(
sum, i - 4, i)).min().getAsInt();
// Since one of the last 4 elements must be
// present
return Arrays.stream(Arrays.copyOfRange(
sum, n - 4, n)).min().getAsInt();
}
// Driver Code
public static void main(String[] args)
{
int ar[] = { 2, 4, 1, 5, 2, 3, 6, 1, 2, 4 };
int n = ar.length;
System.out.println("Minimum sum = " + minSum(ar, n));
}
}
// This code is contributed by PrinciRaj1992
Python3
# Python3 program to calculate
# minimum possible sum for given constraint
# function to calculate min sum using dp
def minSum(ar, n):
# if elements are less than or equal to 4
if (n <= 4):
return min(ar)
# save start four element as it is
sum = [0 for i in range(n)]
sum[0] = ar[0]
sum[1] = ar[1]
sum[2] = ar[2]
sum[3] = ar[3]
# compute sum[] for all rest elements
for i in range(4, n):
sum[i] = ar[i] + min(sum[i - 4:i])
# Since one of the last 4 elements must be
# present
return min(sum[n - 4:n])
# Driver Code
ar = [2, 4, 1, 5, 2, 3, 6, 1, 2, 4]
n = len(ar)
print("Minimum sum = ", minSum(ar, n))
# This code is contributed by Mohit Kumar
C#
// C# program to calculate
// minimum possible sum for given constraint
using System;
using System.Linq;
class GFG
{
// function to calculate min sum using dp
static int minSum(int []ar, int n)
{
// if elements are less than or equal to 4
if (n <= 4)
return ar.Min();
// save start four element as it is
int []sum = new int[n];
sum[0] = ar[0];
sum[1] = ar[1];
sum[2] = ar[2];
sum[3] = ar[3];
int []tempArr;
// compute sum[] for all rest elements
for (int i = 4; i < n; i++)
{
//sum[i] = ar[i] + (*min_element(sum + i - 4, sum + i));
tempArr = new int[4];
Array.Copy(sum, i - 4, tempArr, 0, 4);
sum[i] = ar[i] + tempArr.Min();
}
// Since one of the last 4 elements must be
// present
tempArr = new int[4];
Array.Copy(sum,n-4,tempArr,0,4);
return tempArr.Min();
}
// Driver Code
public static void Main(String[] args)
{
int []ar = { 2, 4, 1, 5, 2, 3, 6, 1, 2, 4 };
int n = ar.Length;
Console.WriteLine("Minimum sum = " +
minSum(ar, n));
}
}
// This code is contributed by Rajput-Ji
输出:
Minimum sum = 4
时间复杂度: O(n)。