zoukankan      html  css  js  c++  java
  • 组合数问题

     原题链接:https://www.luogu.org/problem/show?pid=2822#sub

    做一次不爽一次。仅仅是对我去年考场上没想起来c(i,j) = c(i-1,j) + c(i-1,j-1)的垃圾行为而感到绝望的愤怒。

    (LaTeX用得还暂时不熟练,各位谅解)

    我实在是想不起来我当时是有多大的勇气,在这道题写完暴力不管不问的情况下就去刚T2T3。

    如果您还没学排列组合,那这道题可能暂时不适合您来做。

    如果您学过排列组合(高中数学选修2-3相关内容),应该对一个式子不陌生,就是我刚才在上面写的那个c(i,j) = c(i-1,j) + c(i-1,j-1)。

    这是组合数的一个性质,要完成这道题需要用这个式子进行一下预处理。

    暴力思想很简单,暴力算阶乘,暴力算组合。如果在暴力时稍加改进会如何?

    看到n只有2000,所以可以考虑先把这个范围内的所有c[i][j]都先求出来,就用那个公式,全都推出来就好,边界是c[i][0] = c[i][i] = 1(依据组合数的性质)

    这样我们就有了一个表。如果您学过排列组合,可以输出一下看看,这个表长什么样?

    这可是杨辉三角啊!

    实际上,为了求解方便,在推的时候可以把值对k取模,这样推出来后的c[i][j]如果是0,那么这个就是k的倍数。

    按要求输出即可,这题到此结束。

    哦?是吗?那你可只有90分啊。

    后面那10分卡在哪里了?输出。

    如果不加任何处理,在输出的时候我们也是要遍历一次c数组的,这个操作比较费时间。

    既然c数组可以打表,答案为什么不可以?

    令s[i][j]表示在所有的c(i,j) (1≤j≤i)的里面,为k的倍数的有多少个,那么处理数组的时候就是s[i][j] = s[i][j-1] ,每找到一个s[i][j]为0就让值+1。

    按要求输出即可,这题到此结束。

    行了,这次可以A了。

    参考代码:

     1 #include <iostream>
     2 #define maxn 2005
     3 using namespace std;
     4 int c[maxn][maxn];
     5 int s[maxn][maxn];
     6 int ans[maxn][maxn];
     7 int t,k,n,m;
     8 int main(){
     9     cin >> t >> k;
    10     for (int i=1;i<maxn;i++){
    11         c[i][0] = 1;
    12         c[i][i] = 1;
    13         for (int j=1;j<i;j++)
    14             c[i][j] = (c[i-1][j] + c[i-1][j-1]) % k;
    15     }
    16 
    17     for (int i=1;i<maxn;i++)
    18         for (int j=1;j<=i;j++){
    19             s[i][j] = s[i][j-1];
    20             if (c[i][j] == 0)
    21                 s[i][j]++;
    22         }
    23 
    24     for (int time=1;time<=t;time++){
    25         cin >> n >> m;
    26     
    27         int ans = 0;
    28         for (int i=1;i<=n;i++){
    29             int j = min(i,m);
    30             ans += s[i][j];
    31         }
    32         cout << ans << endl;
    33     
    34     
    35     }    
    36     return 0;
    37 }
  • 相关阅读:
    Node+OBS直播服务器搭建总结
    WebRTC网页录制音视频教程
    人生有尺 做人有度
    「道 德 經」 : 第 二 十 四 章
    看山是山,看水是水;看山不是山,看水不是水;看山还是山,看水还是水。
    「道 德 经」 : 第 八 章
    Ubuntu下安装Chrome浏览器的两个方法
    chromium中增加自己的文件夹
    chromium 切换主分支的方法
    chromium 示例
  • 原文地址:https://www.cnblogs.com/OIerShawnZhou/p/7518444.html
Copyright © 2011-2022 走看看