给定一个由N 个整数组成的数组A和一个正整数K 。在这个数组上只能执行三个操作:
1)用整数的负值替换整数,
2) 将元素的索引号(基于 1 的索引)添加到元素本身并
3) 从元素本身减去元素的索引号。
任务是检查给定的数组是否可以转换,使用上述三个允许的操作中的任何一个,只对每个元素执行一次。使得数组的总和变为 K。
例子:
Input : N = 3, K = 2
A[] = { 1, 1, 1 }
Output : Yes
Explanation
Replace index 0 element with -1. It will sum of array equal to k = 2.
Input : N = 4, K = 5
A[] = { 1, 2, 3, 4 }
Output : Yes
前提条件动态规划
方法这个想法是使用动态规划来解决问题。
声明一个二维布尔数组dp[][] ,其中 dp[i][j] 说明是否有任何方法可以通过对数组的前i 个元素进行一些操作来获得等于j的数组的总和。
如果总和是可能的,则 dp[i][j] 将为真,否则为False 。
此外,数组的中间总和可能为负,在这种情况下,不要执行任何操作并忽略它,从而使总和始终为正,因为 k 始终为正。
为了计算 dp[i][j],如果我们对 a[i] 应用运算并将其添加到总和中,我们需要可以得出总和j的所有状态的值。
下面是这个方法的实现
C++
/* C++ Program to find if Array can have a sum
of K by applying three types of possible
operations on it */
#include
using namespace std;
#define MAX 100
// Check if it is possible to achieve a sum with
// three operation allowed.
int check(int i, int sum, int n, int k, int a[],
int dp[MAX][MAX])
{
// If sum is negative.
if (sum <= 0)
return false;
// If going out of bound.
if (i >= n) {
// If sum is achieved.
if (sum == k)
return true;
return false;
}
// If the current state is not evaluated yet.
if (dp[i][sum] != -1)
return dp[i][sum];
// Replacing element with negative value of
// the element.
dp[i][sum] = check(i + 1, sum - 2 * a[i], n,
k, a, dp) || check(i + 1, sum, n, k, a, dp);
// Substracting index number from the element.
dp[i][sum] = check(i + 1, sum - (i + 1), n,
k, a, dp) || dp[i][sum];
// Adding index number to the element.
dp[i][sum] = check(i + 1, sum + i + 1, n,
k, a, dp) || dp[i][sum];
return dp[i][sum];
}
// Wrapper Function
bool wrapper(int n, int k, int a[])
{
int sum = 0;
for (int i = 0; i < n; i++)
sum += a[i];
int dp[MAX][MAX];
memset(dp, -1, sizeof(dp));
return check(0, sum, n, k, a, dp);
}
// Driver Code
int main()
{
int a[] = { 1, 2, 3, 4 };
int n = 4, k = 5;
(wrapper(n, k, a) ? (cout << "Yes") : (cout << "No"));
return 0;
}
Java
/* Java Program to find if Array can have a sum
of K by applying three types of possible
operations on it */
class GFG
{
static int MAX = 100;
// Check if it is possible to achieve a sum with
// three operation allowed.
static int check(int i, int sum, int n,
int k, int a[], int dp[][])
{
// If sum is negative.
if (sum <= 0)
{
return 0;
}
// If going out of bound.
if (i >= n)
{
// If sum is achieved.
if (sum == k)
{
return 1;
}
return 0;
}
// If the current state is not evaluated yet.
if (dp[i][sum] != -1)
{
return dp[i][sum];
}
// Replacing element with negative value of
// the element.
dp[i][sum] = check(i + 1, sum - 2 * a[i], n, k, a, dp) |
check(i + 1, sum, n, k, a, dp);
// Substracting index number from the element.
dp[i][sum] = check(i + 1, sum - (i + 1), n,
k, a, dp) | dp[i][sum];
// Adding index number to the element.
dp[i][sum] = check(i + 1, sum + i + 1, n,
k, a, dp) | dp[i][sum];
return dp[i][sum];
}
// Wrapper Function
static int wrapper(int n, int k, int a[])
{
int sum = 0;
for (int i = 0; i < n; i++)
{
sum += a[i];
}
int[][] dp = new int[MAX][MAX];
for (int i = 0; i < MAX; i++)
{
for (int j = 0; j < MAX; j++)
{
dp[i][j] = -1;
}
}
return check(0, sum, n, k, a, dp);
}
// Driver Code
public static void main(String[] args)
{
int a[] = {1, 2, 3, 4};
int n = 4, k = 5;
if (wrapper(n, k, a) == 1) {
System.out.println("Yes");
} else {
System.out.println("No");
}
}
}
// This code is contributed by Princi Singh
C#
// C# Program to find if Array can have a sum
// of K by applying three types of possible
using System;
class GFG
{
static int MAX = 100;
// Check if it is possible to achieve a sum with
// three operation allowed.
static int check(int i, int sum, int n,
int k, int []a, int [,]dp)
{
// If sum is negative.
if (sum <= 0)
{
return 0;
}
// If going out of bound.
if (i >= n)
{
// If sum is achieved.
if (sum == k)
{
return 1;
}
return 0;
}
// If the current state is not evaluated yet.
if (dp[i, sum] != -1)
{
return dp[i, sum];
}
// Replacing element with negative value of
// the element.
dp[i,sum] = check(i + 1, sum - 2 * a[i], n, k, a, dp) |
check(i + 1, sum, n, k, a, dp);
// Substracting index number from the element.
dp[i,sum] = check(i + 1, sum - (i + 1), n,
k, a, dp) | dp[i,sum];
// Adding index number to the element.
dp[i,sum] = check(i + 1, sum + i + 1, n,
k, a, dp) | dp[i,sum];
return dp[i, sum];
}
// Wrapper Function
static int wrapper(int n, int k, int []a)
{
int sum = 0;
for (int i = 0; i < n; i++)
{
sum += a[i];
}
int[,] dp = new int[MAX,MAX];
for (int i = 0; i < MAX; i++)
{
for (int j = 0; j < MAX; j++)
{
dp[i, j] = -1;
}
}
return check(0, sum, n, k, a, dp);
}
// Driver Code
static public void Main ()
{
int []a = {1, 2, 3, 4};
int n = 4, k = 5;
if (wrapper(n, k, a) == 1)
{
Console.WriteLine("Yes");
}
else
{
Console.WriteLine("No");
}
}
}
// This code is contributed by ajit_0023
Python3
# Python program to find if Array can have sum
# of K by applying three types of possible
# operations on it
MAX = 100
# Check if it is possible to achieve a sum with
# three operation allowed
def check(i, add, n, k, a, dp):
# if sum id negative.
if add <= 0:
return False
# If going out of bound.
if i >= n:
if add == k:
return True
return False
# If the current state is not evaluated yet.
if dp[i][add] != -1:
return dp[i][add]
# Replacing element with negative value of
# the element.
dp[i][add] = (check(i+1, add-2*a[i], n,
k, a, dp) or check(i+1, add, n, k, a, dp))
# Substracting index number from the element.
dp[i][add] = (check(i+1, add - (i+1), n,
k, a, dp) or dp[i][add])
# Adding index number to the element.
dp[i][add] = (check(i+1, add+i+1, n,
k, a, dp) or dp[i][add])
return dp[i][add]
# Wrapper Function
def wrapper(n, k, a):
add = 0
for i in range(n):
add += a[i]
dp = [-1]*MAX
for i in range(MAX):
dp[i] = [-1]*MAX
return check(0, add, n, k, a, dp)
# Driver Code
if __name__ == "__main__":
a = [1,2,3,4]
n = 4
k = 5
print("Yes") if wrapper(n, k, a) else print("No")
# This code is contributed by
# sanjeev2552
Javascript
输出:
Yes
如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程和学生竞争性编程现场课程。