• Luogu 题解 P2638 【安全系统】


    组合数学


    题目

    题意:有两种不同的球,放入n个箱子中,箱子可以放,也可以不放
    分析:这是一种经典组合题,即往盒子中装球,我们由小学奥数可以得出结论:
    ( ext{ans = }sum^{a}_{i = 0} sum^{b}_{j = 0} ext{C[i + n - 1][n - 1] C[j + n - 1][n - 1]})

    我们得到公式后,还需要一个高效计算组合数的算法,这是我们便想到了杨氏三角:
    众所周知

            1
           1 1
          1 2 1
         1 3 3 1
        1 4 6 4 1
        .........
    

    于是我们得到了一个公式:
    C[i][j] = C[i - 1][j - 1] + C[i - 1][j]
    其中当j == 0 || j == i时,C[i][j] = 1

    得到了一段预处理组合数的代码:

    void Pre_Work() {
    	for(int i = 0; i <= 50; i ++) con[i][0] = con[i][i] = 1;
    	for(int i = 2; i <= 50; i ++)
    		for(int j = 1; j <= i; j ++)
    			con[i][j] = con[i - 1][j] + con[i - 1][j - 1];
    }
    
    #include <cstdio>
    #include <iostream>
    #define int unsigned long long
    //注意要用ull
    using namespace std;
    int read() {
    	int w = 1,res = 0;
    	char ch = getchar();
    	while(ch < '0' || ch > '9') {
    		if(ch == '-') w = -1;
    		ch = getchar();
    	}
    	while(ch >= '0' && ch <= '9') res = res * 10 + ch - '0', ch = getchar();
    	return w * res;
    }
    int con[100][100], ans;
    void Pre_Work() {
    	for(int i = 0; i <= 50; i ++) con[i][0] = con[i][i] = 1;
    	for(int i = 2; i <= 50; i ++)
    		for(int j = 1; j <= i; j ++)
    			con[i][j] = con[i - 1][j] + con[i - 1][j - 1];
    }
    signed main() {
    	int n = read(), a = read(), b = read();
    	Pre_Work();
    	for(int i = 0; i <= a; i ++)
    		for(int j = 0; j <= b; j ++)
    			ans += con[i + n - 1][n - 1] * con[j + n - 1][n - 1];
    	cout << ans;
    	return 0;
    }
    
  • 相关阅读:
    python中使用schedule模块定时执行任务
    python marshmallow库
    shell 脚本根据名称查找进程id会多出来两个id号
    docker随笔(1)
    python实现-kafka作为消息中间件 -实现数据生产和消费-实用的脚本
    python-kafka文档
    mysql文档
    VMware pro15安装centos7
    excel表计算和计算器计算结果不一致
    jmeter安装部署、maven路径配置
  • 原文地址:https://www.cnblogs.com/Wuzhuoming-sirenboke/p/14064372.html
Copyright © 2020-2023  润新知