题目链接

给3个组员分配任务

题目描述

给定四个正整数 。需要将 个任务分配给三位员工(小v、小i、小o),他们能处理的任务上限分别为 。要求计算出所有满足条件的分配方案总数。

一个分配方案指的是一个三元组 ,其中 分别是分配给三位员工的任务数,需要满足以下条件:

解题思路

这是一个简单的组合计数问题。由于所有输入的数值范围都非常小(最大为50),我们可以使用最直观的方法——暴力枚举来解决。

思路是固定其中两位员工的任务数,然后计算出第三位员工需要承担的任务数,最后检查这个分配方案是否满足所有约束条件。

具体算法步骤如下:

  1. 我们用两层循环来枚举分配给小v(任务数 )和小i(任务数 )的所有可能情况。
  2. 小v的任务数 可以从 取到他的上限 ,同时不能超过总任务数 。所以 的取值范围是
  3. 对于每一个确定的 ,小i的任务数 可以从 取到他的上限 ,同时也不能超过剩余的任务数 。所以 的取值范围是
  4. 的值确定后,分配给小o的任务数 也就唯一确定了:
  5. 此时,我们已经通过循环的边界条件保证了 , 以及 。唯一还需要检查的条件就是小o的任务数是否超过他的上限,即
  6. 如果 成立,说明我们找到了一个有效的分配方案,就将总方案数加一。
  7. 遍历完所有可能的 的组合后,累计的总方案数就是最终答案。

代码

#include <iostream>
#include <algorithm>

using namespace std;

class Solution {
public:
    /**
     * 任务分配方案数计算
     * @param n int整型 待分配任务总数
     * @param x int整型 员工小v能处理的任务数上限
     * @param y int整型 员工小i能处理的任务数上限
     * @param z int整型 员工小o能处理的任务数上限
     * @return int整型
     */
    int assignJobs(int n, int x, int y, int z) {
        int count = 0;
        // 枚举小v的任务数v
        for (int v = 0; v <= min(n, x); ++v) {
            // 枚举小i的任务数i
            for (int i = 0; i <= min(n - v, y); ++i) {
                // 计算小o的任务数o
                int o = n - v - i;
                // 检查小o的任务数是否在其能力范围内
                if (o <= z) {
                    count++;
                }
            }
        }
        return count;
    }
};
import java.util.*;

public class Solution {
    /**
     * 任务分配方案数计算
     * @param n int整型 待分配任务总数
     * @param x int整型 员工小v能处理的任务数上限
     * @param y int整型 员工小i能处理的任务数上限
     * @param z int整型 员工小o能处理的任务数上限
     * @return int整型
     */
    public int assignJobs(int n, int x, int y, int z) {
        int count = 0;
        // 枚举小v的任务数v
        for (int v = 0; v <= Math.min(n, x); v++) {
            // 枚举小i的任务数i
            for (int i = 0; i <= Math.min(n - v, y); i++) {
                // 计算小o的任务数o
                int o = n - v - i;
                // 检查小o的任务数是否在其能力范围内
                if (o <= z) {
                    count++;
                }
            }
        }
        return count;
    }
}
class Solution:
    def assignJobs(self , n: int, x: int, y: int, z: int) -> int:
        count = 0
        # 枚举小v的任务数v
        for v in range(min(n, x) + 1):
            # 枚举小i的任务数i
            for i in range(min(n - v, y) + 1):
                # 计算小o的任务数o
                o = n - v - i
                # 检查小o的任务数是否在其能力范围内
                if o <= z:
                    count += 1
        return count

算法及复杂度

  • 算法:暴力枚举
  • 时间复杂度:两层循环的复杂度由 决定。外层循环最多执行 次,内层循环最多执行 次。因此,总的时间复杂度为
  • 空间复杂度:算法只使用了常数个额外变量,因此空间复杂度为