hdu 4602 Partition
来源:互联网 发布:模架编程招聘 编辑:程序博客网 时间:2024/05/21 18:39
一道整数划分的问题,,需要利用组合数学
题意是给一个数n,有2^(n-1)中划分方法,问在这2^(n-1)种方法中数字m出现的次数
例如
3=1+1+1
3=1+2
3=2+1
3=3
则2出现的次数为2.
刚开始想的是利用递推的方式,但是地推的方式不对,变量多一两个我就处理不过来了,唉~~其实是利用排列组合的知识,隔板法
分两种情况:(将n划分为n个1,则连续取m个1)
第一:当取得连续m个数位于首或尾时,就有2^(n-m-1)种取法
第二:当取得的连续数位于中间段时,就有2^(n-m-2)种取法,
所以可以得出公式=(n-m-1)*2^(n-m-2)+2*2^(n-m-1)=(n-m+3)*2^(n-m-2)
注意当n=m,m=1,n-m=1,m>n时特判一下,其实每一种取法就对应在这个位置上出现多少次,无关其他位置的取值,所以把每个位置的取法相加就等于出现的次数了,刚开始时看题解的时候很不明白,忘了是要求出现的次数,我以为求取法所以在相加这个地方纠结了好久,脑子不好使的痛苦~~~(复习了快速幂的写法)
这是另外一种解释:点击打开链接
#include<stdio.h>#include<string.h>#include <iostream>using namespace std;typedef long long LL;const LL mod=1e9+7;LL quick(LL n,LL p){ LL ans=1; while(p>0) { if(p&1) ans=(ans*n)%mod; p>>=1; n=(n*n)%mod; } return ans;}int main(){ int t; LL n,k; scanf("%d",&t); while(t--) { scanf("%I64d%I64d",&n,&k); if(k>n) printf("0\n"); else if(n==k) printf("1\n"); else if(n-k==1) printf("2\n"); else { //cout<<quick(2,n-k-2)<<endl; LL sum=(quick(2,n-k-2)*(n-k+3))%mod; printf("%I64d\n",sum); } } return 0;}
0 0
- hdu - 4602 《Partition》
- HDU 4602 Partition
- HDU 4602 Partition
- hdu-4602-Partition
- hdu 4602 Partition
- HDU 4602 Partition
- hdu 4602 Partition
- hdu(4602) Partition
- hdu 4602 Partition
- HDU 4602 Partition
- hdu 4602 Partition
- HDU 4602 Partition
- HDU 4602 Partition
- hdu 4602 Partition
- HDU 4602 Partition
- HDU 4602 Partition
- HDU 4602 Partition
- hdu 4602 Partition
- Blcoking I/O & NonBlocking I/O
- la4327 优先队列优化dp
- synchronized 方法与锁对象
- 服务器集群监控 Ganglia 搭建 CenOS6.5
- 如何用AWS(亚马逊云服务器)搭建一个自己的BLOG (1) – 申请一个AWS云服务器
- hdu 4602 Partition
- 项目4:换硬币
- redis常见的几种使用场景
- 本地音乐播放器(三)——播放界面和服务的通信
- phpmyadmin使用空密码登入配置方法
- 继承案例
- 读了oracle查询与优化做一些笔记,方便以后查看
- jQuery实现三种漂亮的对话框
- 简单密码