• 【noip2016】组合数问题


    题目描述

    组合数表示的是从n个物品中选出m个物品的方案数。举个例子,从(1, 2, 3)三个物品中选择两个物品可以有(1, 2), (1, 3), (2, 3)这三种选择方法。根据组合数的定义,我们可以给出计算组合数的一般公式:

    其中 n! = 1 x 2 x ... x n。

    小葱想知道如果给定n, m和k,对于所有的0 <= i <= n, 0 <= j <= min(i, m)有多少对(i, j)满足是k的倍数。


    输入

    第一行有两个整数t, k,其中t代表该测试点总共有多少组测试数据,k的意义见【问题描述】。

    接下来t行每行两个整数n, m,其中n, m的意义见【问题描述】。


    输出

    t行,每行一个整数代表所有的0 <= i <= n, 0 <= j <= min(i, m)有多少对(i, j)满足是k的倍数。


    样例输入

    1 2
    3 3


    样例输出

    1




    题解

    递推加前缀和。

    #include<cmath>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    #define ll long long
    
    const int maxn=2000+5;
    
    int t,k,n,m;
    int c[maxn][maxn],s[maxn][maxn];
    
    int main(){
        memset(c,0,sizeof(c));
        memset(s,0,sizeof(s));
        cin>>t>>k;
        for(int i=0;i<=maxn;i++){
            c[i][0]=1;c[i][i]=1;
            for(int j=1;j<i;j++) c[i][j]=(c[i-1][j]+c[i-1][j-1])%k;
        }
        for(int i=1;i<maxn;i++)
        for(int j=1;j<=i;j++){
            s[i][j]=s[i][j-1];
            if(c[i][j]==0) s[i][j]++;
        }
        while(t--){
            cin>>n>>m;
            int ans=0;
            for(int i=1;i<=n;i++){
                int w=min(i,m);
                ans+=s[i][w];
            }
            cout<<ans<<endl;
        }
        return 0;
    }
  • 相关阅读:
    从无到有实现.net协程(二)
    从无到有实现.net协程(一)
    Lombok 安装、入门
    抓取服务器图片下载到本地
    七牛整合php上传从微信下载接口下载下来的文件
    七牛整合PHP上传文件
    大型网站架构演化
    框架计划随笔 三.EntityFramework在传统事务脚本模式下的使用
    框架计划随笔 二.选型
    框架计划随笔 一.背景和愿景
  • 原文地址:https://www.cnblogs.com/rlddd/p/9502447.html
Copyright © 2020-2023  润新知