对于一个定长(size = n)的数列a, 若其存在“位置相关”的子集(含空集)使得该子集所有元素之和为k,那么将数列a计数。

其中数列a中任一元素a[i]在[0, l]内自由取值。

数据条件0≤n, k ≤ 20, 0≤ l ≤ 1e9,计数结果对mod = 1e9 + 7取模。

无论直接计数还是考虑从反面计数都解决不了去重的问题,只能考虑dp。

枚举数列的长度i和压缩后的状态j,并且记录在该条件下的数列选取方案数dp[i][j]。

压缩后的状态j表示对于集合{1, 2, ..., min(l, k)}的选取情况。

其中集合中第i个元素在状态j中当且仅当j的二进制串的第i位为1。

显然我们有dp[0][0] = 1。

对于长度为p的数组,第p位可以选取的元素是0,1,2,...,l

考虑p位选取1,2,...,min(l, k)

那么对于数组长度为p-1时的任一状态j,在数组后追加元素i后的状态为:

j1 = j | ((j << i) & ((1 << k) - 1)) | (1 << (i - 1))

三部分分别表示原状态,原状态每个元素与元素i求和后增加的状态,i本身。

于是dp[p][j1] += dp[p - 1][j]。

而对于p位选取0或者大于min(l, k)的情形,j1 = j。

因此有dp[p][j] = (l - min(l, k)) * dp[p - 1][j]。

我们最后只需对dp[n][j],其中j第k位为1的累加即可。

由于数列每个元素非负,我们最后只关心那些集合存在和为k的子集,

而那些大于k的元素必然不是构成子集的元素,只有那些小于k的元素才对状态转移有用。

因此我们可以这样表示状态。

 #include <cstdio>
#include <cstring>
#include <algorithm>
#include <map>
#include <string>
#include <vector>
#include <set>
#include <cmath>
#include <ctime>
using namespace std;
#define lson (u << 1)
#define rson (u << 1 | 1)
typedef __int64 ll;
const int maxn = 1e6 + ;
const int maxm = ;
const ll mod = 1e9 + ; int n, l, k;
ll dp[( << ) + ];
int main(){
int T;
scanf("%d", &T);
while(T--){
scanf("%d%d%d", &n, &k, &l);
ll d = abs(l - k);
l = min(l, k);
int s = ( << k) - ;
memset(dp, , sizeof dp);
dp[] = ;
while(n--){
for(int j = s; j >= ; j--){
ll tem = dp[j];
if(!tem) continue;
for(int p = ; p <= l; p++){
int nex = ( << (p - )) | j | ((j << p) & s);
dp[nex] = (dp[nex] + tem) % mod;
}
dp[j] = (tem * ( + d)) % mod;
}
}
ll ans = ;
for(int i = s; i >= ; i--)
if(i & ( << (k - )))
ans = (ans + dp[i]) % mod;
printf("%I64d\n",ans);
}
return ;
}

hdoj4906 Our happy ending(2014 Multi-University Training Contest 4)的更多相关文章

  1. HDU4888 Redraw Beautiful Drawings(2014 Multi-University Training Contest 3)

    Redraw Beautiful Drawings Time Limit: 3000/1500 MS (Java/Others)    Memory Limit: 65536/65536 K (Jav ...

  2. hdu 4946 2014 Multi-University Training Contest 8

    Area of Mushroom Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) ...

  3. 2014 Multi-University Training Contest 9#11

    2014 Multi-University Training Contest 9#11 Killing MonstersTime Limit: 2000/1000 MS (Java/Others)   ...

  4. 2014 Multi-University Training Contest 9#6

    2014 Multi-University Training Contest 9#6 Fast Matrix CalculationTime Limit: 2000/1000 MS (Java/Oth ...

  5. 2014 Multi-University Training Contest 1/HDU4861_Couple doubi(数论/法)

    解题报告 两人轮流取球,大的人赢,,, 贴官方题解,,,反正我看不懂.,,先留着理解 关于费马小定理 关于原根 找规律找到的,,,sad,,, 非常easy找到循环节为p-1,每个循环节中有一个非零的 ...

  6. 2014 Multi-University Training Contest 1/HDU4864_Task(贪心)

    解题报告 题意,有n个机器.m个任务. 每一个机器至多能完毕一个任务.对于每一个机器,有一个最大执行时间Ti和等级Li,对于每一个任务,也有一个执行时间Tj和等级Lj.仅仅有当Ti>=Tj且Li ...

  7. 2016 Al-Baath University Training Camp Contest-1

    2016 Al-Baath University Training Camp Contest-1 A题:http://codeforces.com/gym/101028/problem/A 题意:比赛 ...

  8. hdu 4937 2014 Multi-University Training Contest 7 1003

    Lucky Number Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others) T ...

  9. hdu 4941 2014 Multi-University Training Contest 7 1007

    Magical Forest Time Limit: 24000/12000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Other ...

随机推荐

  1. Swift游戏实战-跑酷熊猫 10 视差滚动背景

    原理 实现 勘误 “实现”的视频中有个错误,如下 背景移动时有个错误,看红色部分,近景归位时,第二张图片的下标是1 if arrBG[0].position.x + arrBG[0].frame.wi ...

  2. 自定义FragmentTabHost--实现View重复加载问题

    1,接着上篇的Fragment+FragmentTabHost搭建简单的底部功能切换框架,效果如下: 结果在项目中用到的时候发现Fragment+FragmentTabHost实现的时候每一次切换底部 ...

  3. session讲解(二)——商城购物车练习

    网上商城中“添加商品到购物车”是主要功能之一,所添加的商品都存到了session中,主要以二维数组的形式存储在session中,在这里我们将以买水果为例 第一:整个水果商品列表 <body> ...

  4. HOWTO Install the MinGW (GCC) Compiler Suite

    Posted July 25th, 2008 by mingwadmin getting started install mingw Automated Installer If you are ne ...

  5. java 网络编程(一)---基础知识和概念了解

    java 为用户提供了十分完善的网络功能: 1. 获取网络上的各种资源(URL) 2. 与服务器建立连接和通信(ServerSocket和Socket) 3. 无连接传递本地数据(DatagramSo ...

  6. zw版【转发·台湾nvp系列Delphi例程】HALCON SetMshape

    zw版[转发·台湾nvp系列Delphi例程]HALCON SetMshape procedure TForm1.FormShow(Sender: TObject);var img : HImageX ...

  7. jquery表单重置另一种方法

    页面中按钮为<a>标签时,点击取消按钮,表单内容重置,需要给form表单id="form": <a class="demo_one1" onc ...

  8. string与char之间的互相转换

    string对象是一种很强大的存在哈~~ 1. string转const char* string s = "abc"; const char* c_s = s.c_str(); ...

  9. drupal 做301跳转(删除url里的www), 关键代码 可用到任何网站

    //hook_init(); function ex_init(){ //删除 url 前面的 www if (substr($_SERVER['HTTP_HOST'],0,3) == 'www'){ ...

  10. android 学习随笔十七(服务 )

    1.Service 四大组件之一 运行于后台,没有前台界面的组件,用于运行需要在后台运行的代码 可以理解为没有前台的Activity 定义方式:创建java类继承Service,清单文件中注册该类 p ...