• 【SGU】476 Coach's Trouble


    题意:有3*n个人,分成n组,每组三个人。给出k个三元组,这三个人不可组队,问最后可以组队的总方案数。

    当k=0时,有(C[3*n][3]*C[3*n-3][3]*……*C[3][3])/n!种方案,展开以后可以得到dp[n]=(3*n)!/n!/6^n。

    显然可以写成递推式:dp[n]=dp[n-1]*(3*n-1)*(3*n-2)/2。

    那么容斥一下,答案=总方案数-至少含一个禁止组合的+至少含两个禁止组合的-……

    二进制暴力TLE了。DFS的话会有很多剪枝,当前几个已经出现冲突,自然不会再往后面搜了。

     1 import java.util.*;
     2 import java.math.*;
     3 
     4 public class Solution {
     5     static int group[][] = new int[25][3];
     6     static int cnt[] = new int[25];
     7     static boolean vis[] = new boolean[3001];
     8     static int n, k, depth;
     9 
    10     static void Init() {
    11         int i;
    12         for (i = 0; i < 25; i++)
    13             cnt[i] = 0;
    14         for (i = 0; i < 3001; i++)
    15             vis[i] = false;
    16     }
    17 
    18     static void DFS(int index, int now) {
    19         if (now == depth) {
    20             if (depth % 2 == 1)
    21                 cnt[depth]++;
    22             else
    23                 cnt[depth]--;
    24         } else {
    25             int i;
    26             for (i = index; i < k; i++) {
    27                 if (vis[group[i][0]] == false && vis[group[i][1]] == false
    28                         && vis[group[i][2]] == false) {
    29                     vis[group[i][0]] = vis[group[i][1]] = vis[group[i][2]] = true;
    30                     DFS(i + 1, now + 1);
    31                     vis[group[i][0]] = vis[group[i][1]] = vis[group[i][2]] = false;
    32                 }
    33             }
    34         }
    35     }
    36 
    37     public static void main(String[] args) {
    38         Scanner in = new Scanner(System.in);
    39         int i, j;
    40         BigInteger dp[] = new BigInteger[1001];
    41         BigInteger res;
    42         dp[0] = dp[1] = BigInteger.ONE;
    43         for (i = 2; i < 1001; i++)
    44             dp[i] = dp[i - 1].multiply(BigInteger.valueOf(3 * i - 1))
    45                     .multiply(BigInteger.valueOf(3 * i - 2))
    46                     .divide(BigInteger.valueOf(2));
    47         while (in.hasNext()) {
    48             Init();
    49             n = in.nextInt();
    50             k = in.nextInt();
    51             for (i = 0; i < k; i++) {
    52                 for (j = 0; j < 3; j++)
    53                     group[i][j] = in.nextInt();
    54             }
    55             for (depth = 1; depth <= k; depth++)
    56                 DFS(0, 0);
    57             res = BigInteger.ZERO;
    58             for (i = 1; i <= k; i++) {
    59                 if (cnt[i] != 0)
    60                     res = res
    61                             .add(dp[n - i].multiply(BigInteger.valueOf(cnt[i])));
    62             }
    63             System.out.println(dp[n].subtract(res));
    64         }
    65     }
    66 }
  • 相关阅读:
    品鉴-宋词
    【转载】全球水质最棒的十大景点
    Python文档管理与格式化工具
    Python音频处理
    Python剪切板提取、截图、图片粘贴,操作汇总
    Python多进程
    Wifi配置
    条码生成与解析
    谎言: “太空能看到的惟一的人工痕迹,长城!”
    VNC-Server安装配置详解
  • 原文地址:https://www.cnblogs.com/DrunBee/p/2674850.html
Copyright © 2020-2023  润新知