腾讯笔试——安排座位(动态规划)

题目描述

为了给腾讯公司找到更多优秀的人才,HR湫秋最近去某高校组织了一次针对该校所有系的聚会,邀请了每个系的一些优秀学生来参加。

  作为组织者,湫秋要安排他们的座位。这并不是一件很简单的事情,因为只有一排位置,并且位置总数恰好等于参加聚会的人数。为了促进交流,两个来自相同系的同学不可以座位相邻。湫秋现在希望知道有多少种不同的合理安排座位的方法(任意两个合理的安排方法,只要有一个位置的同学不同,都被认为是不同的)。

输入

输入第一行为T,表示有T组测试数据。
每组数据一个N开始,表示一共有多少个系。下面的一行包含N个整数Ai,表示每个系的到场人数。
1 <= T <= 47
1 <= N, Ai <= 47
1 <= Sum(Ai) <= 447

输出

对每组数据,先输出为第几组数据,然后输出结果。由于结果可能很大,输出对1,000,000,007 取余后的结果。

例子

Sample Input:

3 2 1 2 2 1 3 3 1 2 3

Sample Output:

2
0
120

参考思路:https://www.douban.com/note/269136472/

#include
using namespace std;
int Fac(int n) {
    if (n == 1)
        return 1;
    return n * Fac(n - 1);
}
long long solve(int c, int n, int *a) 
{
    if (c == n)
        return Fac(c);
    int i, j;
    long long ans = 0;
    i = 0;
    for (j = 0; j < n; j++)
        if (a[j] > a[i])
            i = j;
    j = i;
    a[j] -= 1;
    int x = (c - 2 * a[j]);
    ans = solve(c - 1, n, a) * x;
    for (i = 0; i < n; i++) {
        if (i != j && a[i] > 1) {
            a[i] -= 1;
            ans += 2 * solve(c - 2, n, a);
            a[i] += 1;
        }
    }
    a[j] += 1;
    return ans;
}
int main()
{
    int loop, n, a[47], i, c;
    cin >> loop;
    while (loop--) {
        cin >> n;
        c = 0;
        for (i = 0; i < n; i++) {
            cin >> a[i];
            c += a[i];
        }
        cout << solve(c, n, a) % 1000000007 <return 0;
}

你可能感兴趣的:(算法,腾讯)