给定两个数组coin []和salaries [] ,其中coin [i]表示第i个硬币的值,而salaries [j]表示第j个工人将接受的硬币的最小值。任务是计算向每个工人准确分配一枚硬币的方式数量。由于答案可能很大,因此请以10 9 + 7为模数打印。
例子:
Input: coins[] = {1, 2, 3}, salaries[] = {1, 2}
Output: 4
Explanation:
If the coin with value 1 is not used, then the remaining two coins are acceptable by both workers, contributing two possible ways to pay the workers.
If the coin with value 1 is used, then it can only be used for the first worker. Then either of the remaining coins can be used to pay the second worker. This also contributes to two possible ways.
Therefore, the four ways to pay the two workers are [2, 3], [3, 2], [1, 2], [1, 3].
Input: coins[] = {1, 2}, salaries[] = {2}
Output: 1
方法:想法是使用排序和两个指针技术解决该问题。请按照以下步骤解决问题:
- 按降序对薪水进行排序。
- 令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)