• Cheerleaders UVA - 11806


    Cheerleaders - UVA 11806 - Virtual Judge

    题目大意:有一个n*m的网格,要把其中k个格子涂黑,且满足最上、下一行、最左、右一列分别至少有一格黑,问方案数有多少

    2<=m,n<=50;k<=500

    思路:因为合法的方案数不好考虑,所以考察不合法的方案数,我们设第一行没有黑格为A,第一列没有黑格为B,最后一行没有黑格为C,最后一列没有黑格为D,根据容斥原理有:非法方案数=-A-B-C-D+AB+AC+AD+BC+BD+CD-ABC-ABD-ACD-BCD+ABCD,这些都可以用组合数算,就是从除了选中行/列以外的格子里选k个,例如A=C[n*m-m][k],AB=C[n*m-n-m+1][k]。

    因为题目中的模数不是质数,所以不能用常规打表阶乘逆元的方法算,因为数据范围很小,所以可以用递推转移的方法打表,首先初始化C[i][0]和C[i][i]都是1,对于1到i-1,有c[i][j]=C[i-1]j]+C[i-1][j-1],我们将15个几何都算出来求和即可。

    1. #include
    2. //#include<__msvc_all_public_headers.hpp>
    3. using namespace std;
    4. typedef long long ll;
    5. const int N = 1e6 + 5;
    6. const ll MOD = 1e6 + 7;
    7. ll n;
    8. ll inv[N], fac[N];
    9. ll C[405][405];
    10. void calC()
    11. {//打表预处理组合数
    12. C[0][0] = 1;
    13. for (int i = 1; i <= 400; i++)
    14. {
    15. C[i][0] = C[i][i] = 1;//边界都是1
    16. for (int j = 1; j < i; j++)
    17. {//中间用类似杨辉三角的形式转移
    18. C[i][j] = C[i - 1][j] + C[i - 1][j - 1] % MOD;
    19. }
    20. }
    21. }
    22. void solve(int t)
    23. {
    24. ll m, k;
    25. cin >> n >> m >> k;
    26. ll ans = C[n * m][k];//总方案数
    27. ans = (ans - C[n * m - n][k] + MOD) % MOD;//A
    28. ans = (ans - C[n * m - n][k] + MOD) % MOD;//B
    29. ans = (ans - C[n * m - m][k] + MOD) % MOD;//C
    30. ans = (ans - C[n * m - m][k] + MOD) % MOD;//D
    31. ans = (ans + C[n * m - n - m + 1][k]) % MOD;//AB
    32. ans = (ans + C[n * m - n - m + 1][k]) % MOD;//AD
    33. ans = (ans + C[n * m - n - n][k]) % MOD;//AC
    34. ans = (ans + C[n * m - m - m][k]) % MOD;//BD
    35. ans = (ans + C[n * m - m - n + 1][k]) % MOD;//BC
    36. ans = (ans + C[n * m - n - m + 1][k]) % MOD;//CD
    37. ans = (ans - C[n * m - 2 * n - m + 2][k] + MOD) % MOD;//ABC
    38. ans = (ans - C[n * m - 2 * n - m + 2][k] + MOD) % MOD;//ACD
    39. ans = (ans - C[n * m - 2 * m - n + 2][k] + MOD) % MOD;//BCD
    40. ans = (ans - C[n * m - 2 * m - n + 2][k] + MOD) % MOD;//ABD
    41. ans = (ans + C[n * m - 2 * m - 2 * n + 4][k]) % MOD;//ABCD
    42. cout << "Case " << t << ": " << ans % MOD << endl;
    43. }
    44. int main()
    45. {
    46. ios::sync_with_stdio(false);
    47. cin.tie(0);
    48. int t;
    49. cin >> t;
    50. calC();
    51. int cnt = 0;
    52. while (t--)
    53. {
    54. cnt++;
    55. solve(cnt);
    56. }
    57. return 0;
    58. }

  • 相关阅读:
    排序---堆排
    「行泊一体」市场有多大?2025年前装搭载率将超40%
    Java基于JSP旅游网站系统的设计于实现
    06实战:如何通过 ref 实现组件的子传父、父传子的交互(实例演示)?
    Linux自动化任务管理以及常见定时命令示例
    Spelling sentences
    【C++ Primer Plus】第4章 复合类型
    Prompt-Tuning(一)
    适用于STM32的U8G2回调函数例程
    玩机进阶教程------修改gpt.bin分区表地址段 完全屏蔽系统更新 fast刷写分区表 操作步骤解析【二】
  • 原文地址:https://blog.csdn.net/ashbringer233/article/details/133526214