首页 > 其他 > 详细

【NOIP2016】组合数问题

时间:2017-09-17 23:55:46      阅读:391      评论:0      收藏:0      [点我收藏+]

题目描述 Description

技术分享

 

输入描述 Input Description

从标准输入读入数据。

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

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

输出描述 Output Description

输出到标准输出。

tt 行,每行一个整数代表所有的 0in,0jmin(i,m) 中有多少对 (i,j)(满足 Cji 是 k 的倍数。

样例输入 Sample Input

1 2
3 3

样例输出 Sample Output

1

数据范围及提示 Data Size & Hint

技术分享

 

之前的一些废话:还有两周运动会,争取收获两块奖牌。后天要搞大事情。

题解:NOIP2016D2T1智障题,不要问我为什么去年只得了30分(无比悲惨的回忆)。组合数递推C(n,m)=C(n-1,m)+C(n-1,m-1),然后取模,维护一个二维前缀和即可。

代码:

技术分享
#include<iostream>
#include<cmath>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
typedef long long LL;
typedef pair<int,int> PII;
#define mem(a,b) memset(a,b,sizeof(a))
inline int read()
{
     int x=0,f=1;char c=getchar();
     while(!isdigit(c)){if(c==-)f=-1;c=getchar();}
     while(isdigit(c)){x=x*10+c-0;c=getchar();}
     return x*f;
}
const int maxn=2010;
int T,K,c[maxn][maxn],sum[maxn][maxn],cnt[maxn][maxn];
int main()
{
    T=read();K=read();
    mem(c,-1);
    c[0][0]=1;
    for(int i=1;i<=2000;i++)c[i][0]=1,c[i][i]=1;
    for(int i=1;i<=2000;i++)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<=2000;i++)for(int j=1;j<=2000;j++)sum[i][j]=sum[i][j-1]+(c[i][j]==0);
    for(int i=1;i<=2000;i++)cnt[1][i]=sum[1][i];
    for(int i=1;i<=2000;i++)for(int j=1;j<=2000;j++)cnt[i][j]=cnt[i-1][j]+sum[i][j];
    while(T--)printf("%d\n",cnt[read()][read()]);
    return 0;
}
View Code

总结:去年的我是一个白痴。

【NOIP2016】组合数问题

原文:http://www.cnblogs.com/FYH-SSGSS/p/7538492.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!