题意:

  Given a sequence a_1,a_2,...,a_n, if we can take some of them(each a_i can only be used once), and they sum to k, then we say this sequence is a good sequence.
   How many good sequence are there? Given that each a_i is an integer and 0<= a_i <= L.

  给你一个序列: a_1, a_2, ..., a_n,如果我们能够取出他们中的一些(每个a_i只能取一次),并且他们的和是k,我们就把这个序列称为一个好的序列。

  如果每个a_i都是0到L中的整数,那么他们一共能组成多少好序列呢?

思路:

  状态压缩。

  dp[i][S]表示长度为i的序列,能组合成的加和的集合为S的情况有多少种(集合用数字的位来表示,1表示可以组成,0表示不可以。因为有用的数字最多只有20,所以可以这样表示)。

  这样,我们可以枚举第i+1位,得到一个新的可以组成的数的集合。原理和背包类似。 在和别人的讨论中发现,用位运算可以很方便的表示这个背包的内容,我们假设原本可以组成的集合为S,现在枚举放不放进背包的数是j。那么,不放进背包的时候可能组成的集合还是S;而放进背包的话,可能组成的集合就变成了(S<<j);所以枚举j可能组成的所有集合就是 S|(S<<j) 看起来是不是很简洁。

  所以这样,我们的转移方程就可以写成 dp[i+1][S] = sum{dp[i][S0] | (S0|(S0<<j) ) == S}

  值得注意的是,直接开 n*2^n 的数组可能会爆内存,观察转移是一层一层的进行的,所以我们可以用滚动数组进行优化。

(最后,感谢alpc同学的耐心讲解 :)

代码:(这样做会跑2秒,真心不知道那些0毫秒的怎么做的Orz)

 #include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <algorithm>
#include <string>
#include <queue>
#include <stack>
#include <vector>
#include <map>
#include <set>
#include <functional>
#include <time.h> using namespace std; typedef __int64 ll; const int INF = <<;
const int MAXN = ;
const ll MOD = (ll) 1e9+; ll dp[<<MAXN];
int n, k, L; void solve() {
memset(dp, , sizeof(dp));
int MIN = min(L, k);
int FULL = (<<(k+))-; //全集 dp[] = ;
for (int i = ; i < n; i++) {
for (int S = FULL; S > ; S--) if (dp[S]>) {
ll tmp = dp[S];
for (int j = ; j <= MIN; j++) //枚举每一个有效数字
dp[FULL&(S|(S<<j))] = (dp[FULL&(S|(S<<j))]+tmp)%MOD;
if (MIN<L)
dp[S] = (dp[S]+((L-MIN)*tmp)%MOD)%MOD;
}
} ll ans = ;
for (int S = ; S <= FULL; S++) if (S&(<<(k)))
ans = (ans+dp[S])%MOD; printf("%I64d\n", ans);
} int main() {
#ifdef Phantom01
freopen("HDU4906.txt", "r", stdin);
#endif //Phantom01 int T;
scanf("%d", &T);
while (T--) {
scanf("%d%d%d", &n, &k, &L);
solve();
} return ;
}

HDU 4906 Our happy ending的更多相关文章

  1. HDU 4906 Our happy ending (状压DP)

    HDU 4906 Our happy ending pid=4906" style="">题目链接 题意:给定n个数字,每一个数字能够是0-l,要选当中一些数字.然 ...

  2. HDU 4906 Our happy ending(2014 Multi-University Training Contest 4)

    题意:构造出n个数 这n个数取值范围0-L,这n个数中存在取一些数之和等于k,则这样称为一种方法.给定n,k,L,求方案数. 思路:装压 每位 第1为表示这种方案能不能构成1(1表示能0表示不能)   ...

  3. HDU 4906 状态压缩dp

    Our happy ending Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Other ...

  4. hdu 4906 3-idiots fft

    题目链接 n个火柴棍取3个, 问能组成三角形的概率是多少. kuangbin大神的博客写的很详细了..http://www.cnblogs.com/kuangbin/archive/2013/07/2 ...

  5. HDU 4906 (dp胡乱搞)

    The Romantic Her Problem Description There is an old country and the king fell in love with a devil. ...

  6. HDU 1542 Atlantis(线段树扫描线+离散化求面积的并)

    Atlantis Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total S ...

  7. hdu 1086(计算几何入门题——计算线段交点个数)

    链接:http://acm.hdu.edu.cn/showproblem.php?pid=1086 You can Solve a Geometry Problem too Time Limit: 2 ...

  8. hdu 5154 Harry and Magical Computer

    题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=5154 Harry and Magical Computer Description In reward ...

  9. hdu 1038 Biker&#39;s Trip Odometer(水题)

    题目链接:http://acm.hdu.edu.cn/showproblem.php? pid=1038 Biker's Trip Odometer Time Limit: 2000/1000 MS ...

随机推荐

  1. Photoshop CC (2015.5) 2016.6 版已发布

    Photoshop CC (2015.5) 2016.6 版已发布 adobe-cc-no-more-direct-download-links.html 不再有直接下载的升级包了,不开心 :( 下载 ...

  2. mybatis批量插入、批量更新和批量删除

    转载 https://www.jianshu.com/p/041bec8ae6d3

  3. Eclipse schema xml提示

    步骤一:确定xsd文件位置 spring-framework-3.2.0.RELEASE\schema\beans  步骤二:复制路径  步骤三:搜索“xml catalog”  步骤四:添加约束提示 ...

  4. php如何实现文件下载

    php如何实现文件下载 1. 设置超链接的href属性 <ahref="文件地址"></a> 如果浏览器不能解析该文件,浏览器会自动下载.而如果文件是图片或 ...

  5. js产生随机数的几个方法

    1.Math.random(); 结果为0-1间的一个随机数(包括0,不包括1) 2.Math.floor(num); 参数num为一个数值,函数结果为num的整数部分. 3.Math.round(n ...

  6. iOS系统的特点-iOS为什么运行更流畅

    1.进程管理机制-不允许后台进程: 2.用户事件响应优先级: 3.GPU加速: 4.系统内存管理机制: 5.运行机制-机器码直接运行-非虚拟机.

  7. NodeJS学习笔记 (6)网络服务-http-res(ok)

    原文:https://github.com/chyingp/nodejs-learning-guide 自己敲代码: 概览 http模块四剑客之一的res,应该都不陌生了.一个web服务程序,接受到来 ...

  8. 从A小程序跳转到B小程序

    从A小程序跳转到B小程序: A小程序 wxml: <navigator target="miniProgram" open-type="navigate" ...

  9. Python排序 插入排序

    插入排序从前往后遍历数组的每一个元素,对每一位元素都将其插入到已经有序的部分数组中,所以插入排序的要点就是找出要插入元素在已经有序的部分中的位置,同时,由于插入排序采用原地排序(in-place)算法 ...

  10. 2015 Multi-University Training Contest 3 hdu 5316 Magician

    Magician Time Limit: 18000/9000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total S ...