博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
nyoj743-复杂度 【排列组合】
阅读量:5767 次
发布时间:2019-06-18

本文共 1215 字,大约阅读时间需要 4 分钟。

 

复杂度

时间限制:
1000 ms  |  内存限制:65535 KB
难度:
3
 
描述

for(i=1;i<=n;i++)

  for(j=i+1;j<=n;j++)

    for(k=j+1;k<=n;k++)

        operation;

你知道 operation 共执行了多少次吗;

 
输入
输入 m 和n 表示m为for循环的层数,n为for中的n。
(n,m<=2000),输入以n==0和m==0结束
输出
输出operation执行的次数(输入结果mod 1009)
样例输入
2 31 32 40 0
样例输出
336
解题思路:

首先m层,每层都有一个值 i、j、k….我们发现这m个值是不重复的,而且是递增序列,于是我们可以想到只需要计算总共有多少中m个数的组合的情况即可,即C(n,m)   —– 从n中任选m个数的种类数。每取出m个数,再递增对应安排在原for循环里,即是一种情况。但是问题又来了,n和m的值最大为2000,因此求C(n,m) 的时候long long 也存不下,而且(n%mod)/(m%mod) != (n/m)%mod;

这就又需要用到另外的一个公式

C(n,m)= C (n-1,m) + C (n-1,m-1);

根据递推公式打表完美解决。

代码:

1 #include 
2 #include
3 #include
4 #include
5 6 using namespace std; 7 8 #define ll long long 9 #define N 200110 11 int dp[N][N];12 13 void GetAns();14 15 int main(){16 GetAns();17 int m,n;18 while(scanf("%d %d",&m,&n),m||n){19 if(m>n) puts("0");20 else printf("%d\n",dp[n][m]);21 }22 return 0;23 }24 void GetAns(){25 int N1=N-1;26 for(int i=1;i<=N1;i++) dp[i][0]=1,dp[i][i]=1;27 for(int i=1;i<=N1;i++){28 for(int j=i-1;j>0;j--){29 dp[i][j]=(dp[i-1][j]+dp[i-1][j-1])%1009;30 }31 }32 }
View Code

 

转载地址:http://jcfux.baihongyu.com/

你可能感兴趣的文章
linux已经不存在惊群现象
查看>>
上位机和底层逻辑的解耦
查看>>
学习进度条
查看>>
关于微信二次分享 配置标题 描述 图片??
查看>>
springcloud使用zookeeper作为config的配置中心
查看>>
hystrix实战之javanica
查看>>
校园火灾Focue-2---》洗手间的一套-》电梯
查看>>
css控制文字换行
查看>>
bzoj1913
查看>>
bzoj2301(莫比乌斯反演)
查看>>
【转】对于HttpClient和HtmlUnit的理解
查看>>
L104
查看>>
分镜头脚本
查看>>
ASP.NET中的cookie编程技术
查看>>
链表基本操作的实现(转)
查看>>
邮件发送1
查看>>
[转] libcurl异步方式使用总结(附流程图)
查看>>
编译安装LNMP
查看>>
[转]基于display:table的CSS布局
查看>>
企业级 SpringBoot 教程 (二)Spring Boot配置文件详解
查看>>