列表

详情


WY57. 工作方案

描述

牛牛手中有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

原站题解

C 解法, 执行用时: 2ms, 内存消耗: 364KB, 提交时间: 2019-08-04

  
int main()
{
    long long  mod =1000000007;
  
    int cnk[51][51];
    int s;
    scanf("%d",&s);
    int x[3];
    int i,j,t;
    for(i=0;i<3;i++)
    {
        scanf("%d",&x[i]);
          
    }
  
    for (i = 1, cnk[0][0] = 1; i<51; i++) //动态规划求c(n,k)
    {
        cnk[i][0] = 1;
        for (j = 1; j <51; j++)
        {
            cnk[i][j] = (cnk[i - 1][j - 1] + cnk[i - 1][j]) % mod; //没有取余的话会溢出
        }
    }
  
    for(i=0;i<3-1;i++)//对x排序,从小到大,保证x2最大,x0最小
    {
        for(j=i+1;j<3;j++)
        {
            if(x[i]>x[j])
            {
                t=x[i];
                x[i]=x[j];
                x[j]=t;
            }
        }
    }
      
  
    long long cnt=0;
    int left;
    int tmp;
    left = s - x[2]; //给工作量最大的分配后,剩余工作量
  
  
    for(i = 0; i <= left; i++) //i是x1在left中分担的工作量
    {
        if(i <= x[1] && left - i <= x[0])//left - i是x0在left中分担的工作量
        {
            tmp = cnk[x[2]][x[1] - i] % mod; // 在x2中,有x[1] - i分配给x1
            tmp = (tmp * cnk[left][i]) % mod; // left中有i个分配给x1
            tmp = (tmp * cnk[s - (left - i)][x[0] - (left - i)]) % mod; // x0的随意挑选部分
            cnt = (cnt + tmp) % mod; //每个case求和
        }
           
    }
    cnt = (cnt * cnk[s][x[2]]) % mod; //求和后与最初的情况求积
      
    printf("%d\n",cnt);
       
    return 0;
}

C++ 解法, 执行用时: 2ms, 内存消耗: 376KB, 提交时间: 2020-08-11

#include <iostream>
#include <vector>
#include <math.h>
#include <algorithm>
using namespace std;

int main() {
    int s;
    vector<int> member(3);
    while (cin >> s >> member[0] >> member[1] >> member[2]) {
        sort(member.begin(), member.end());
        vector<vector<int> > C(s  + 1, vector<int> (s + 1));
        C[0][0] = 1;
        for (int i = 1; i <= s; i++) {
            C[i][0] = 1;
            for (int j = 1; j <= s; j++) {
                C[i][j] = (C[i - 1][j - 1] + C[i - 1][j]) % 1000000007;
            }
        }
        int left = s - member[2];
        long temp, ans = 0;
        for (int i = 0; i <= left; i++) {
            if (i <= member[1] && left - i <= member[0]) {
                temp = C[member[2]][member[1] - i] % 1000000007;
                temp = temp * C[left][i] % 1000000007;
                temp = temp * C[s - left + i][member[0] - left + i] % 1000000007;
                ans = (ans + temp) % 1000000007;
            }
        }
        ans = (ans * C[s][member[2]]) % 1000000007;
        cout << ans << endl;
    }
    return 0;
}

上一题