题意:

  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. Android TextView加下划线的几种方式

    如果是在资源文件里: <resources> <</u></string> <string name="app_name">M ...

  2. 配置 centos apache 的日志文件为每天保存,在home分区

    /usr/local/apache/bin/rotatelogs 这个执行程序会根据安装方式不同的位置也不同,yum安装的话,路径为:/usr/sbin/rotatelogs 改为: ErrorLog ...

  3. hiho1080 - 数据结构 线段树(入门题,两个lazy tag)

    题目链接 维护区间和,两个操作:一个是将某个区间设置成一个值,一个是将某个区间增加一个固定值 /**************************************************** ...

  4. nginx的rewrite规则

    301跳转: server { listen 80; server_name www.xiaofan.com; return 301 https://$server_name$request_uri; ...

  5. 洛谷 P1983 车站分级 拓扑排序

    Code: #include<cstdio> #include<queue> #include<algorithm> #include<cstring> ...

  6. HDU-3065 病毒侵袭持续中 字符串问题 AC自动机

    题目链接:https://cn.vjudge.net/problem/HDU-3065 题意 跟上一道题是几乎一模一样,这次是统计关键词的出现次数 一个相当坑的地方,注意多组样例 思路 套模版 改in ...

  7. [洛谷P3948]数据结构

    题目大意:有n个数,opt个操作,并给你md.min.max. 每种操作有以下两种:1.给一段区间加一个固定值.2.询问一段区间内满足$min\leq T*i\ mod\ md\leq max$(T是 ...

  8. 学习Keras:《Keras快速上手基于Python的深度学习实战》PDF代码+mobi

    有一定Python和TensorFlow基础的人看应该很容易,各领域的应用,但比较广泛,不深刻,讲硬件的部分可以作为入门人的参考. <Keras快速上手基于Python的深度学习实战>系统 ...

  9. pandas 7 合并 merge 水平合并,数据会变宽

    pd.merge( df1, df2, on=['key1', 'key2'], left_index=True, right_index=True, how=['left', 'right', 'o ...

  10. CentOS上手动配置nginx.services

    [Unit] Description=Dynamic web platform based on NGINX and LuaJIT After=network.target remote-fs.tar ...