📌  相关文章
📜  检查是否可以通过三个运算将数组和设为K

📅  最后修改于: 2021-04-24 14:49:13             🧑  作者: Mango

给定一个由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

前提条件动态编程

方法这个想法是使用动态编程来解决问题。
声明一个2D布尔数组dp [] [] ,其中dp [i] [j]声明是否有任何方法可以使用对该数组的前i个元素进行某些操作来获得等于j的数组之和。
如果总和是可能的,则dp [i] [j]将为true ,否则为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


输出:
Yes