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

📅  最后修改于: 2021-05-06 07:28:05             🧑  作者: 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.

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


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 
#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。
为此,我们使用前缀和。我们设置i和j,并检查i到j – 1之间的排序数组是否得出sum <= x,其余元素也得出sum 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; 
} 

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

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