首页 > 试题广场 >

工作方案

[编程题]工作方案
  • 热度指数:77 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 150M,其他语言300M
  • 算法知识视频讲解
牛牛手中有s份工作需要完成,牛牛准备将工作分给三位员工。考虑到三位员工还有其他工作需要做,牛牛规定他们每人必须要参与的工作数量分别是a,b,c。
牛牛需要制定详细的工作方案,需要满足每份工作至少有一个人做,同一份工作可以由两个或者三个人共同参与。牛牛一下意识到可能的工作方案很多,牛牛需要你帮他计算一下一共有多少种不同的工作方案(对于两种方案,如果某份工作分配的人或者人数不一样就考虑为不一样的工作方案)。

对于输入样例,s = 3, a = 3, b = 1, c = 1
a要参与所有三份工作,b和c各自有三种选择,所以不同的工作方案是3 * 3 * 1= 9
如果s = 3, a = 1, b = 1, c = 1
相当于对三个员工做全排列,所以不同的工作方案是3 * 2 * 1 = 6

输入描述:
输入包括一行,一行包括4个正整数s,a,b,c(1 ≤ s ≤ 50, 1 ≤ a, b, c ≤ s),分别表示需要完成的工作份数,每个员工必须要参与的工作数量。


输出描述:
输出一个正整数,表示不同的方案种数,答案可能很大,输出答案对1000000007取模。
示例1

输入

3 3 1 1

输出

9

数学

甲先选择a份工作,还剩下rest=s-a份工作;接下来乙选工作,假设他在rest中选了i份工作(i需要进行枚举),那么剩下的b-i份工作就要在a中选;最后丙选工作,他可以从rest-i中选一部分,剩下的c-(rest-i)份工作在甲和乙已经选过的a+i份工作中选,而这两部分,只要一部分确定了,另一部分就确定了。
import java.io.*;
import java.util.*;

public class Main {
    final static int MOD = 1000000007;
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String line;
        while((line = br.readLine()) != null){
            String[] params = line.split(" ");
            int s = Integer.parseInt(params[0]);
            int a = Integer.parseInt(params[1]);
            int b = Integer.parseInt(params[2]);
            int c = Integer.parseInt(params[3]);
            long count = 0;
            int rest = s - a;    // 第一个选完后,剩下的工作数
            for (int i = Math.max(Math.max(0, rest - c), b - a); i <= Math.min(b, rest); i++) {
                count += ((combination(i, rest)* combination(b - i, a) % MOD) * combination(c - rest + i, a + i)) % MOD;
            }
            count *= combination(a, s);
            System.out.println(count % MOD);
        }
    }
    
    private static long combination(int m, int n) {
        double d = 1;
        for(int i = 0, len = m; i < len; i++) {
            d = d * n-- / m--;
        }
        return (long)Math.round(d) % MOD;
    }
}

编辑于 2022-03-05 16:47:12 回复(0)