zoukankan      html  css  js  c++  java
  • Noip2016提高组 组合数问题problem

    Day2 T1

    题目大意

    告诉你组合数公式,其中n!=1*2*3*4*5*...*n;意思是从n个物体取出m个物体的方案数

    现给定n、m、k,问在所有i(1<=i<=n),所有j(1<=j<=min(i,m))的(i,j)满足Cji是k的倍数的个数。

    输入样例:
    2 5  (两个数,第一个数t表示该数据有t组询问,第二个为k,接下来t行分别为n,m)
    4 5  
    6 7
    输出样例:
    0
    7

    数据范围:1<=n,m<=2000,1<=t<=10000,1<=k<=21

    数论题,当时做竟然没发现这就是个杨辉三角,就是少了第一列全是1的,真是悲剧。

    组合数的递推式就是Cmn=Cm-1n-1+Cmn-1

    因为k一开始就固定了,所以预处理2000以内的个数,用前缀和优化优化就可以AC了,当然用二维前缀和似乎能优化到O(1),不麻烦每行一个前缀和到时候O(n)的得出答案也不会超时。

    比完赛了也赶快转C++了23333

     1 #include<cstdio>
     2 #include<iostream>
     3 #include<cstring>
     4 #include<cmath>
     5 using namespace std;
     6 int a[2005][2005],ji[2005][2005];
     7 int n,m,ans,t,k;
     8 int main(){
     9     scanf("%d%d",&t,&k);
    10     memset(a,0,sizeof(a));
    11     a[1][1]=1%k;
    12     if (a[1][1]==0) ji[1][1]++;
    13     for (int j=2;j<=2001;j++)
    14      for (int q=1;q<=min(j,2001);q++){
    15          if (q==1) a[j][q]=(a[j-1][q]+1)%k;
    16           else a[j][q]=(a[j-1][q]+a[j-1][q-1])%k;
    17           if (a[j][q]==0) ji[j][q]=ji[j][q-1]+1; else ji[j][q]=ji[j][q-1];
    18           }
    19     for (int i=1;i<=t;i++){
    20         scanf("%d%d",&n,&m);
    21         ans=0;
    22         for (int j=1;j<=n;j++)
    23          ans+=ji[j][min(m,j)];
    24         printf("%d
    ",ans);
    25     }
    26     return 0;      
    27     }
    神奇的代码
  • 相关阅读:
    004_列表list操作
    003_字符串str的操作
    002_python基础语录
    求哈夫曼树的编码
    Python笔记(一)——打印输出
    python基础一 day33 验证客户端的合法性
    python基础一 day32 复习
    python基础一 day30 网络编程
    python基础一 day29 logging
    python基础一 day29 学习方法(课前谈心)
  • 原文地址:https://www.cnblogs.com/Lanly/p/6126173.html
Copyright © 2011-2022 走看看