📌  相关文章
📜  计算分配给每个工人一枚硬币的方式

📅  最后修改于: 2021-05-17 22:55:37             🧑  作者: Mango

给定两个数组coin []salaries [] ,其中coin [i]表示第i硬币的值,而salaries [j]表示第j工人将接受的硬币的最小值。任务是计算向每个工人准确分配一枚硬币的方式数量。由于答案可能很大,因此请以10 9 + 7为模数打印。
例子:

方法:想法是使用排序和两个指针技术解决该问题。请按照以下步骤解决问题:

  • 按降序对薪水进行排序。
  • f(i)是在没有其他任何工人的情况下用来支付第i工人的硬币数量。由于薪金[]数组已排序,因此第一个工人要求最高薪水,最后一个工人要求最低薪水。因此,结果是:
  • 对于函数f(i)i等于可用于支付当前工人的代币数量,假定所有先前的工人均已支付。
  • 由于按薪水的递增顺序对工人进行了分类,因此用于支付前工人的任何硬币都可以保证用来支付当前工人的工资。因此,可用于支付当前工人的代币数量将始终等于f(i)-i ,与先前做出的选择无关。
  • 为了有效地计算f(i) ,请使用两个指针跟踪当前有效的硬币数量。
  • 完成上述所有步骤后,打印方法总数。

下面是上述方法的实现:

C++
// C++ program for the above approach
 
#include 
using namespace std;
 
const int MOD = 1000000007;
 
// Function to find number of way to
// distribute coins giving exactly one
// coin to each person
int solve(vector& values,
          vector& salary)
{
    long long ret = 1;
    int amt = 0;
 
    // Sort the given arrays
    sort(values.begin(), values.end());
    sort(salary.begin(), salary.end());
 
    // Start from bigger salary
    while (salary.size()) {
        while (values.size()
               && values.back()
                      >= salary.back()) {
 
            // Increment the amount
            amt++;
            values.pop_back();
        }
        if (amt == 0)
            return 0;
 
        // Reduce amount of valid
        // coins by one each time
        ret *= amt--;
        ret %= MOD;
        salary.pop_back();
    }
 
    // Return the result
    return ret;
}
 
// Driver code
int main()
{
    // Given two arrays
    vector values{ 1, 2 }, salary{ 2 };
 
    // Function Call
    cout << solve(values, salary);
 
    return 0;
}


Java
// Java program for
// the above approach
import java.util.*;
class GFG{
 
static int MOD = 1000000007;
 
// Function to find number of way to
// distribute coins giving exactly one
// coin to each person
static int solve(Vector values,
                 Vector salary)
{
  int ret = 1;
  int amt = 0;
 
  // Sort the given arrays
  Collections.sort(values);
  Collections.sort(salary);
 
  // Start from bigger salary
  while (salary.size() > 0)
  {
    while (values.size() > 0 &&
           values.get(values.size() - 1) >=
           salary.get(salary.size() - 1))
    {
      // Increment the amount
      amt++;
      values.remove(values.size() - 1);
    }
     
    if (amt == 0)
      return 0;
 
    // Reduce amount of valid
    // coins by one each time
    ret *= amt--;
    ret %= MOD;
    salary.remove(salary.size() - 1);
  }
 
  // Return the result
  return ret;
}
 
// Driver code
public static void main(String[] args)
{
  // Given two arrays
  Vector values = new Vector();
  values.add(1);
  values.add(2);
  Vector salary = new Vector();
  salary.add(2);
   
  // Function Call
  System.out.print(solve(values, salary));
}
}
 
// This code is contributed by Princi Singh


Python3
# Python3 program for the above approach
MOD = 1000000007
 
# Function to find number of way to
# distribute coins giving exactly one
# coin to each person
def solve(values, salary):
     
    ret = 1
    amt = 0
 
    # Sort the given arrays
    values = sorted(values)
    salary = sorted(salary)
 
    # Start from bigger salary
    while (len(salary) > 0):
        while ((len(values) and
                values[-1] >= salary[-1])):
 
            # Increment the amount
            amt += 1
            del values[-1]
 
        if (amt == 0):
            return 0
 
        # Reduce amount of valid
        # coins by one each time
        ret *= amt
        amt -= 1
        ret %= MOD
        del salary[-1]
 
    # Return the result
    return ret
 
# Driver code
if __name__ == '__main__':
     
    # Given two arrays
    values = [ 1, 2 ]
    salary = [2]
 
    # Function call
    print(solve(values, salary))
 
# This code is contributed by mohit kumar 29


C#
// C# program for
// the above approach
using System;
using System.Collections;
class GFG{
  
static int MOD = 1000000007;
  
// Function to find number of way to
// distribute coins giving exactly one
// coin to each person
static int solve(ArrayList values,
                 ArrayList salary)
{
  int ret = 1;
  int amt = 0;
  
  // Sort the given arrays
  values.Sort();
  salary.Sort();
  
  // Start from bigger salary
  while (salary.Count > 0)
  {
    while (values.Count > 0 &&
           (int)values[values.Count - 1] >=
           (int)salary[salary.Count - 1])
    {
      // Increment the amount
      amt++;
      values.RemoveAt(values.Count - 1);
    }
      
    if (amt == 0)
      return 0;
  
    // Reduce amount of valid
    // coins by one each time
    ret *= amt--;
    ret %= MOD;
    salary.RemoveAt(salary.Count - 1);
  }
  
  // Return the result
  return ret;
}
  
// Driver code
public static void Main(string[] args)
{
  // Given two arrays
  ArrayList values = new ArrayList();
  values.Add(1);
  values.Add(2);
  ArrayList salary = new ArrayList();
  salary.Add(2);
 
  // Function Call
  Console.Write(solve(values, salary));
}
}
 
// This code is contributed by Rutvik_56


输出:
1




时间复杂度: O(N * log N)
辅助空间: O(1)