📜  检查是否所有人都可以在两台机器上投票

📅  最后修改于: 2021-09-17 06:42:50             🧑  作者: Mango

n个人和两个相同的投票机。我们还给出了一个大小为 n 的数组a[] ,使得a[i]存储第 i 个人去任何机器、标记他的投票并返回所需的时间。在某一时刻,每台机器上只能有一个人。给定一个值 x,定义机器运行的最大允许时间,检查是否所有人都可以投票。

例子:

Input  : n = 3, x = 4
         a[] = {2, 4, 2}
Output: YES
There are  n = 3 persons say and maximum
allowed time is x = 4 units. Let the persons
be P0, P1, and P2 and two machines be M0 and M1.
At t0: P0 goes to M0
At t0: P2 goes to M1
At t2: M0 is free, p3 goes to M0
At t4: both M0 and M1 are free and all 3 have
        given their vote.

方法一
sum为所有 n 个人花费的总时间。如果 sum <=x,那么答案显然是 YES。否则,我们需要检查给定的数组是否可以分成两部分,使得第一部分的总和和第二部分的总和都小于或等于 x。这个问题类似于背包问题。想象两个背包,每个背包的容量为 x。现在找到可以在任何一台机器上投票的最大人数,即找到容量为 x 的背包的最大子集总和。让这个总和为 s1。现在如果 (sum-s1) <= x,那么答案是 YES 否则答案是 NO。

C++
// C++ program to check if all people can
// vote using two machines within limited
// time
#include
using namespace std;
 
// Returns true if n people can vote using
// two machines in x time.
bool canVote(int a[], int n, int x)
{
    // dp[i][j] stores maximum possible number
    // of people among arr[0..i-1] can vote
    // in j time.
    int dp[n+1][x+1];
    memset(dp, 0, sizeof(dp));
 
    // Find sum of all times
    int sum = 0;
    for (int i=0; i<=n; i++ )
        sum += a[i];
 
    // Fill dp[][] in bottom up manner (Similar
    // to knapsack).
    for (int i=1; i<=n; i++)
        for (int j=1; j<=x; j++)
            if (a[i] <= j)
                dp[i][j] = max(dp[i-1][j],
                        a[i] + dp[i-1][j-a[i]]);
            else
                dp[i][j] = dp[i-1][j];
 
    // If remaining people can go to other machine.
    return (sum - dp[n][x] <= x);
}
 
// Driver code
int main()
{
    int n = 3, x = 4;
    int a[] = {2, 4, 2};
    canVote(a, n, x)? cout << "YES\n" :
                      cout << "NO\n";
    return 0;
}


Java
// Java program to check if all people can
// vote using two machines within limited
// time
public class Main
{
    // Returns true if n people can vote using
    // two machines in x time.
    static boolean canVote(int[] a, int n, int x)
    {
        // dp[i][j] stores maximum possible number
        // of people among arr[0..i-1] can vote
        // in j time.
        int[][] dp = new int[n + 1][x + 1];
        for(int i = 0; i < n + 1; i++)
        {
            for(int j = 0; j < x + 1; j++)
            {
                dp[i][j] = 0;
            }
        }
       
        // Find sum of all times
        int sum = 0;
        for (int i = 0; i < n; i++ )
            sum += a[i];
       
        // Fill dp[][] in bottom up manner (Similar
        // to knapsack).
        for (int i = 1; i < n; i++)
            for (int j = 1; j <= x; j++)
                if (a[i] <= j)
                    dp[i][j] = Math.max(dp[i - 1][j], a[i] + dp[i - 1][j - a[i]]);
                else
                    dp[i][j] = dp[i - 1][j];
       
        // If remaining people can go to other machine.
        return (sum - dp[n][x] >= x);
    }
     
    public static void main(String[] args) {
        int n = 3, x = 4;
        int[] a = {2, 4, 2};
        if(canVote(a, n, x))
        {
            System.out.println("YES");
        }
        else{
            System.out.println("NO");
        }
    }
}
 
// This code is contributed by mukesh07.


Python3
# Python3 program to check if all people can
# vote using two machines within limited
# time
 
# Function returns true if n people can vote
# using two machines in x time.
def canVote(a, n, x):
     
    # dp[i][j] stores maximum possible number
    # of people among arr[0..i-1] can vote
    # in j time.
    dp = [[0] * (x + 1) for _ in range(n + 1)]
    a = a[:]
    a.append(0)
 
    # Find sum of all times
    sm = 0
    for i in range(n + 1):
        sm += a[i]
 
    # Fill dp[][] in bottom up manner
    # (Similar to knapsack).
    for i in range(1, n + 1):
        for j in range(1, x + 1):
            if a[i] <= j:
                dp[i][j] = max(dp[i - 1][j], a[i] +
                               dp[i - 1][j - a[i]])
            else:
                dp[i][j] = dp[i - 1][j]
 
    # If remaining people can go to other machine.
    return (sm - dp[n][x]) <= x
 
# Driver Code
if __name__ == "__main__":
    n = 3
    x = 4
    a = [2, 4, 2]
    print("YES" if canVote(a, n, x) else "NO")
 
# This code is contributed
# by vibhu4agarwal


C#
// C# program to check if all people can
// vote using two machines within limited
// time
using System;
class GFG {
     
    // Returns true if n people can vote using
    // two machines in x time.
    static bool canVote(int[] a, int n, int x)
    {
        // dp[i][j] stores maximum possible number
        // of people among arr[0..i-1] can vote
        // in j time.
        int[,] dp = new int[n + 1, x + 1];
        for(int i = 0; i < n + 1; i++)
        {
            for(int j = 0; j < x + 1; j++)
            {
                dp[i, j] = 0;
            }
        }
      
        // Find sum of all times
        int sum = 0;
        for (int i = 0; i < n; i++ )
            sum += a[i];
      
        // Fill dp[][] in bottom up manner (Similar
        // to knapsack).
        for (int i = 1; i < n; i++)
            for (int j = 1; j <= x; j++)
                if (a[i] <= j)
                    dp[i, j] = Math.Max(dp[i - 1, j],
                            a[i] + dp[i - 1, j - a[i]]);
                else
                    dp[i, j] = dp[i - 1, j];
      
        // If remaining people can go to other machine.
        return (sum - dp[n, x] >= x);
    }
 
  // Driver code
  static void Main()
  {
    int n = 3, x = 4;
    int[] a = {2, 4, 2};
    if(canVote(a, n, x))
    {
        Console.Write("YES");
    }
    else{
        Console.Write("NO");
    }
  }
}
 
// This code is contributed by rameshtravel07.


Javascript


C++
// C++ program to check if all people can
// vote using two machines within limited
// time
#include
using namespace std;
 
// Returns true if n people can vote using
// two machines in x time.
bool canVote(vector a, int n, int x)
{
    // calculate total sum i.e total
    // time taken by all people
    int total_sum = 0;
    for(auto x : a){
        total_sum += x;
    }
     
    // if total time is less than x then
    // all people can definitely vote
    // hence return true
    if(total_sum <= x)
        return true;
     
    // sort the vector
    sort(a.begin(), a.end());
     
    // declare a vector presum of same size
    // as that of a and initialize it with 0
    vector presum(a.size(), 0);
 
    // prefixsum for first element
    // will be element itself
    presum[0] = a[0];
    // fill the array
    for(int i = 1; i < presum.size(); i++){
        presum[i] = presum[i - 1] + a[i];
    }
 
    // Set i and j and check if array
    // from i to j - 1 gives sum <= x
    for(int i = 0; i < presum.size(); i++){
        for(int j = i + 1; j < presum.size(); j++){
            int arr1_sum = (presum[i] +
                           (total_sum - presum[j]));
            if((arr1_sum <= x) &&
                        (total_sum - arr1_sum) <= x)
                return true;
        }   
    }
     
    return false;
}
 
// Driver code
int main()
{
    int n = 3, x = 4;
    vectora = {2, 4, 2};
    canVote(a, n, x)? cout << "YES\n" :
                      cout << "NO\n";
    return 0;
}


Python3
# Python3 program to check if all people can
# vote using two machines within limited
# time
 
# Returns true if n people can vote using
# two machines in x time.
def canVote(a, n, x):
 
    # calculate total sum i.e total
    # time taken by all people
    total_sum = 0
    for i in range(len(a)):
        total_sum += a[i]
     
    # if total time is less than x then
    # all people can definitely vote
    # hence return true
    if(total_sum <= x):
        return True
     
    # sort the list
    a.sort()
     
    # declare a list presum of same size
    # as that of a and initialize it with 0
    presum = [0 for i in range(len(a))]
 
    # prefixsum for first element
    # will be element itself
    presum[0] = a[0]
     
    # fill the array
    for i in range(1, len(presum)):
        presum[i] = presum[i - 1] + a[i]
     
    # Set i and j and check if array
    # from i to j - 1 gives sum <= x
    for i in range(0, len(presum)):
        for j in range(i + 1, len(presum)):
            arr1_sum = (presum[i] + (total_sum - presum[j]))
            if((arr1_sum <= x) and
               (total_sum - arr1_sum) <= x):
                return True
     
    return False
 
# Driver code
n = 3
x = 4
a = [2, 4, 2]
if(canVote(a, n, x)):
    print("YES")
else:
    print("NO")
 
# This code is contributed by ashutosh450


输出:

YES

时间复杂度: O(x * n)
辅助空间: O(x * n)

方法二
上面的方法使用了 O(x * n) 额外空间,这里我们给出一个使用 O(n) 额外空间的方法。
想法是对数组进行排序,然后检查是否可以得到任何两个数组,它们可以是一个子数组,它可以在数组的开头和结尾之间,使其总和小于或等于 x,其余元素的总和也小于比x。
为此,我们使用前缀 sum。我们设置 i 和 j 并检查 i 到 j – 1 之间的排序数组是否给出 sum <= x,其余元素的总和也为 sum <= x。

C++

// C++ program to check if all people can
// vote using two machines within limited
// time
#include
using namespace std;
 
// Returns true if n people can vote using
// two machines in x time.
bool canVote(vector a, int n, int x)
{
    // calculate total sum i.e total
    // time taken by all people
    int total_sum = 0;
    for(auto x : a){
        total_sum += x;
    }
     
    // if total time is less than x then
    // all people can definitely vote
    // hence return true
    if(total_sum <= x)
        return true;
     
    // sort the vector
    sort(a.begin(), a.end());
     
    // declare a vector presum of same size
    // as that of a and initialize it with 0
    vector presum(a.size(), 0);
 
    // prefixsum for first element
    // will be element itself
    presum[0] = a[0];
    // fill the array
    for(int i = 1; i < presum.size(); i++){
        presum[i] = presum[i - 1] + a[i];
    }
 
    // Set i and j and check if array
    // from i to j - 1 gives sum <= x
    for(int i = 0; i < presum.size(); i++){
        for(int j = i + 1; j < presum.size(); j++){
            int arr1_sum = (presum[i] +
                           (total_sum - presum[j]));
            if((arr1_sum <= x) &&
                        (total_sum - arr1_sum) <= x)
                return true;
        }   
    }
     
    return false;
}
 
// Driver code
int main()
{
    int n = 3, x = 4;
    vectora = {2, 4, 2};
    canVote(a, n, x)? cout << "YES\n" :
                      cout << "NO\n";
    return 0;
}

蟒蛇3

# Python3 program to check if all people can
# vote using two machines within limited
# time
 
# Returns true if n people can vote using
# two machines in x time.
def canVote(a, n, x):
 
    # calculate total sum i.e total
    # time taken by all people
    total_sum = 0
    for i in range(len(a)):
        total_sum += a[i]
     
    # if total time is less than x then
    # all people can definitely vote
    # hence return true
    if(total_sum <= x):
        return True
     
    # sort the list
    a.sort()
     
    # declare a list presum of same size
    # as that of a and initialize it with 0
    presum = [0 for i in range(len(a))]
 
    # prefixsum for first element
    # will be element itself
    presum[0] = a[0]
     
    # fill the array
    for i in range(1, len(presum)):
        presum[i] = presum[i - 1] + a[i]
     
    # Set i and j and check if array
    # from i to j - 1 gives sum <= x
    for i in range(0, len(presum)):
        for j in range(i + 1, len(presum)):
            arr1_sum = (presum[i] + (total_sum - presum[j]))
            if((arr1_sum <= x) and
               (total_sum - arr1_sum) <= x):
                return True
     
    return False
 
# Driver code
n = 3
x = 4
a = [2, 4, 2]
if(canVote(a, n, x)):
    print("YES")
else:
    print("NO")
 
# This code is contributed by ashutosh450

如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程学生竞争性编程现场课程