给定两个数组coins[]和salary[] ,其中coins[i]代表第i个硬币的价值, salary[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个工人的硬币数量。由于对salary[]数组进行了排序,因此第一个工人要求最高工资,最后一个工人要求最低工资。因此,结果是:
- 对于函数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
Javascript
1
时间复杂度: O(N*log N)
辅助空间: O(1)
如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程和学生竞争性编程现场课程。