codeforces 932E Team Work(组合数学、dp)
codeforces 932E Team Work
题意
给定 \(n(1e9)\)、\(k(5000)\)。求 \(\Sigma_{x=1}^{n}C_n^xx^k\)。
题解
解法一
官方题解 的做法,网上有很多,就不写了。
解法二
从组合数学的角度入手。
参考博客
我们可以这样理解这个式子 \(\Sigma_{x=1}^{n}C_n^xx^k\) :有 \(n\) 种小球,从中选出 \(x\) 种,再选出 \(k\) 个小球,这 \(k\) 个小球只能来自选定的 \(x\) 种类别。求方案数。
如果我们用 \(f[i][j]\) 表示 \(i\) 个小球刚好来自某 \(j\) 个种类的方案数。那么 \(\Sigma_{x=1}^{n}C_n^xx^k \equiv \Sigma_{i=1}^{min(n, k)}f_{k,i}*2^{n-i}\) 。
\(f_{k,i}*2^{n-i}\) 可以这样理解:对于选出的某 \(k\) 个小球,有多少种选出小球种数的方案。
\(f_{i,j}\) 的转移如下:\(f_{i,j}=j*f_{i-1,j}+(n-(j-1))*f_{i-1,j-1}\)
//
今天看到一个理解(k=2时)
假设一个公司n个人,挑x个人出来进行抽奖,抽两次奖的方案数就是\(\Sigma_{x=1}^{n}C_n^xx^2\)
从另一个角度枚举所有方案数:只有一个人中奖:\(n2^{n-1}\) 有两个人中奖:\(n(n-1)2^{n-2}\)
解法三
官方题解的评论区 laderlappen 的做法
化简给出的式子,得到的新的式子可以用 \(dp\) 求解。
解法四
化简之后,变成一个和斯特林数有关的式子。
解法五
官方题解的评论区 _rqy 和 retrograd 的做法
\(ans(n, k)=2^n*f_k(n)\), \(f_k(n)\) 是一个 \(k\) 阶多项式,可以用拉格朗日插值法求出。
代码
解法一
#include<bits/stdc++.h>
using namespace std;
#define fi first
#define se second
#define mp make_pair
#define pb push_back
#define rep(i, a, b) for(int i=(a); i<(b); i++)
#define sz(x) (int)x.size()
#define de(x) cout<< #x<<" = "<<x<<endl
#define dd(x) cout<< #x<<" = "<<x<<" "
typedef long long ll;
typedef pair<int, int> pii;
typedef vector<int> vi;
const int N=5005, mod=1e9+7;
int n,k;
ll f[N][N];
ll upd(ll &a, ll b) {
a+=b;
if(a>=mod) a-=mod;
}
ll kpow(ll a,ll b) {
ll res=1;
while(b) {
if(b&1) res=res*a%mod;
a=a*a%mod;
b>>=1;
}
return res;
}
ll solve(int a, int b, int c) {
if(~f[a][b]) return f[a][b];
if(a==0) return f[a][b]=kpow(2, c);
ll res=0;
if(c) {
upd(res, b*solve(a-1, b, c)%mod);
upd(res, c*solve(a-1, b+1, c-1)%mod);
} else {
res=kpow(b, a);
}
return f[a][b]=res;
}
int main() {
while(~scanf("%d%d",&n,&k)) {
memset(f,-1,sizeof(f));
printf("%lld\n",solve(k, 0, n));
}
return 0;
}
解法二
#include<bits/stdc++.h>
using namespace std;
#define fi first
#define se second
#define mp make_pair
#define pb push_back
#define rep(i, a, b) for(int i=(a); i<(b); i++)
#define sz(x) (int)x.size()
#define de(x) cout<< #x<<" = "<<x<<endl
#define dd(x) cout<< #x<<" = "<<x<<" "
typedef long long ll;
typedef pair<int, int> pii;
typedef vector<int> vi;
const int N=5005, mod=1e9+7;
int n,k;
ll f[N][N];
ll upd(ll &a, ll b) {
a+=b;
if(a>=mod) a-=mod;
}
ll kpow(ll a,ll b) {
ll res=1;
while(b) {
if(b&1) res=res*a%mod;
a=a*a%mod;
b>>=1;
}
return res;
}
int main() {
while(~scanf("%d%d",&n,&k)) {
memset(f,0,sizeof(f));
f[0][0]=1;
rep(i,1,k+1) {
rep(j,1,min(n, k)+1) {
upd(f[i][j], j*f[i-1][j]%mod);
upd(f[i][j], (n-j+1)*f[i-1][j-1]%mod);
}
}
ll ans=0;
rep(i,1,min(n, k)+1) upd(ans, f[k][i]*kpow(2, n-i)%mod);
printf("%lld\n",ans);
}
return 0;
}
codeforces 932E Team Work(组合数学、dp)的更多相关文章
- Codeforces 932E Team work 【组合计数+斯特林数】
Codeforces 932E Team work You have a team of N people. For a particular task, you can pick any non-e ...
- 2018.12.14 codeforces 932E. Team Work(组合数学)
传送门 组合数学套路题. 要求ans=∑i=0nCni∗ik,n≤1e9,k≤5000ans=\sum_{i=0}^n C_n^i*i^k,n\le 1e9,k\le 5000ans=∑i=0nCn ...
- Codeforces 932E Team Work 数学
Team Work 发现网上没有我这种写法.. i ^ k我们可以理解为对于每个子集我们k个for套在一起数有多少个. 那么我们问题就变成了 任意可重复位置的k个物品属于多少个子集. 然后我们枚举k个 ...
- Codeforces 886E Maximum Element 组合数学 + dp
我们定义dp[ i ]表示长度为 i 的序列, 最后没有一个==k的时候返回的方案数, 也就是最后强制返回 i 的方案数. 我们能得到dp方程 dp[ i ] = sum(dp[ i - j - ...
- [Codeforces 932E]Team Work
Description 题库链接 求 \[\sum_{i=1}^n C(n,i)\times i^k\] \(1\leq n\leq 10^9, 1\leq k\leq 5000\) Solution ...
- 【uoj#22】[UR #1]外星人 组合数学+dp
题目描述 给你一个长度为 $n$ 的序列 $\{a_i\}$ 和一个数 $x$ ,对于任意一个 $1\sim n$ 的排列 $\{p_i\}$ ,从 $1$ 到 $n$ 依次执行 $x=x\ \tex ...
- 【bzoj1925】[Sdoi2010]地精部落 组合数学+dp
题目描述 传说很久以前,大地上居住着一种神秘的生物:地精. 地精喜欢住在连绵不绝的山脉中.具体地说,一座长度为 N 的山脉 H可分 为从左到右的 N 段,每段有一个独一无二的高度 Hi,其中Hi是1到 ...
- [BZOJ 3625] [Codeforces 438E] 小朋友的二叉树 (DP+生成函数+多项式开根+多项式求逆)
[BZOJ 3625] [Codeforces 438E] 小朋友的二叉树 (DP+生成函数+多项式开根+多项式求逆) 题面 一棵二叉树的所有点的点权都是给定的集合中的一个数. 让你求出1到m中所有权 ...
- Codeforces - 1081C - Colorful Bricks - 简单dp - 组合数学
https://codeforces.com/problemset/problem/1081/C 这道题是不会的,我只会考虑 $k=0$ 和 $k=1$ 的情况. $k=0$ 就是全部同色, $k=1 ...
随机推荐
- c++类型形参的实参的受限转换
缘起:<c++ primer> 4th, 528页,习题16.3 源程序 #include <iostream> #include <vector> #includ ...
- i.mx6 Android6.0.1分析input子系统:测试
getevent与sendevent工具 Android系统提供了getevent与sendevent两个工具供开发者从设备节点中直接读取输入事件或写入输入事件. 在这里,我们测试音量加和音量减按键 ...
- Android四大组件--服务(Service)
1. startService和bindService的区别 1. startService: 生命周期: onCreate---onStartCommand---onDestory 与服务的通讯: ...
- 泛型委托Func<T>
Func<T>——委托只有泛型版本的,接受参数个数可以是若干个,也可以没有,但是必须是有返回值的方法. Func<TResult>——这个表示没有参数,只有返回值TResult ...
- Winform截图小程序
今天闲时做的一个Demo,做得并不好,只是实现了最基本的截图功能 主要的思路就是 先打开一个主窗体,点击"截图按钮" 会出现一个半透明的小窗体(可以拉伸放大缩小) 然后利用Grap ...
- MVC知识点
一· MVC MVC设计模式->MVC框架(前端开发框架),asp.net(webform) aspx M:Model (模型,负责业务逻辑处理,比如说去db中获取数据) V:View (视图 ...
- [PHP] 试题系统研究
考试科目: 添加考试科目,填写科目名称,选择科目题型(复选框/单选题,多选题,判断题,问答题,填空题) 添加科目章节,填写章节名称,添加章节知识点,填写知识点以英文逗号分隔,直接插入多条记录 开通考场 ...
- [javaSE] GUI(对话框Dialog)
对话框不能单独存在,依赖于窗体,有显示标题,有模式 获取Dialog对象,new出来,构造参数:Frame对象,String的标题,模式 窗体内部的内容,Label对象,Button对象,调用Dial ...
- 一、Java多线程基础
一.简介 1.操作系统 在早起的裸机时代,计算机非常地昂贵,而且也没有操作系统的概念,计算机从头到尾只能执行一个程序.如果程序在执行一个耗时的操作,那么在这个过程中,计算机就有大量的资源闲置在那里,这 ...
- shell文本操作
一.find查找命令的使用 1.find . -name "*.txt" 在当前目录下,查找以txt结尾的文件 2.find . -name "[a-z]" 在 ...