题意:

  

分析:

  考虑如何求方案数

  dp[i][j]表示i个数字的和为j的方案数,这是个经典问题,转移有两种,一个是填一个数字1,一个是整体加1

  然后这个问题并不是求方案数,而是求对应的权值和

  我们很容易想到dp[i][j]维护对应的m个下降幂Σx^i,最后再用斯特林数还原成m次幂

  但这样时间复杂度是O(nmk)的,无法接受

  题解给出了一个很妙的想法,我们去计算每个数字对答案的贡献,我们只关心这个数字出现的次数,不妨设我们现在考虑数字x

  x出现总次数={x恰好出现一次的方案数}*1+{x恰好出现两次的方案数}*2+......

  这样无法求解

  但可以转换成这样:

  x出现总次数={x至少出现一次的方案数}+{x至少出现两次的方案数}+.......

        =dp[k-1][n-x]+dp[k-2][n-2x]+dp[k-3][n-3x]+.......

  这样就可以O(nk)解决了

 #include<bits/stdc++.h>
using namespace std;
const int maxn=,mod=1e9+;
int dp[maxn+][maxn+];
int n,k,m;
int ans=;
void inc(int &a,int b)
{
a=(a+b)%mod;
}
int Pow(long long a,int b)
{
long long ans=;
while(b)
{
if(b&) ans=ans*a%mod;
a=a*a%mod;
b>>=;
}
return ans;
}
int main()
{ scanf("%d%d%d",&n,&k,&m);
dp[][]=;
for(int i=;i<=k;++i)
for(int j=;j<=n;++j)
{
if(j>=)
inc(dp[i][j],dp[i-][j-]);
if(j>=i-)
inc(dp[i][j],dp[i][j-i]);
}
for(int i=;i<=n;++i)
{
int s=;
for(int j=;j<=k&&i*j<=n;++j)
inc(s,dp[k-j][n-i*j]);
inc(ans,1LL*s*Pow(1LL*i,m)%mod);
}
printf("%d\n",ans);
return ;
}

最新文章

  1. 数据结构 B-树和B+树的应用:数据搜索和数据库索引
  2. CentOS7 增加tomcat 启动,停止,使用systemctl进行配置
  3. java 21 - 7 IO流小结的图解
  4. C开发基础--函数调用栈
  5. bodyParser注意“需要请求头的支持”
  6. 台电幻彩u盘拆解
  7. Hibernate API申明事务边界
  8. HTML的盒子模型
  9. 在C#中使用GDAL创建Shape文件
  10. C++ 类中的引用成员变量初始化
  11. header 头各种类型文件下载
  12. git用代码库文件完全覆盖本地/git不能提交jar的设置
  13. Learning Structured Representation for Text Classification via Reinforcement Learning 学习笔记
  14. ubuntu 使用旧式Gnome风格的菜单
  15. ecna2017-Game of Throwns
  16. windows10安装ubuntu16.04双系统
  17. win10安装OpenSSL及简单的使用
  18. c++静态变量与菲静态变量
  19. 安装vmware虚拟机和linux(centos)
  20. matlab 基本操作

热门文章

  1. PAT (Basic Level) Practise (中文)-1029. 旧键盘(20)
  2. 【JavaScript】两种常见JS面向对象写法
  3. How To:Linux下如何通过命令检查网卡是否插上网线
  4. Luogu P4231 三步必杀 (差分)
  5. redis集群理解
  6. ajax实现上传图片保存到后台并读取
  7. S3C6410串口平台设备注册流程分析
  8. ACM-ICPC 2018 南京赛区网络预赛 L. Magical Girl Haze
  9. EFCore CodeFirst模型迁移生成数据库备注(mysql)
  10. [android开发篇]elicpse安装教程