Our happy ending
- 题意:
输入n、k、L,n个数,最大值不超过L,在序列中取若干个数和能达到k的序列个数
n,k<=20 , 0<=L<=10^9 - 分析:
题目关键在于和k比較小,所以能够考虑DP。
先说一下自己比赛时候想到的DP状态。好久才发现错了。。。。
DP[i][j]表示当前是序列中的第i个数(必须选),和能取到j的序列个数。
这个状态的问题就是在于反复:对于一个确定的序列来说,由于能够选取某些数字来求和,所以对于DP[i]来说,同一个序列能够得到非常多不同的和j,也就是被计算了非常多次从而导致反复。
对照一下之前见过的一个类似的问题,给定一个序列。问取若干个数能达到和k的方案数:DP[i][j]表示当前是序列中的第i个数(必须选),和能取到j的序列个数,这个问题这样表示就是正确的了。
为什么会这样呢?就是由于答案的推断方式不同:第一个问题的答案推断是,当前序列假设能取到若干个数使得和为k。那么答案加一;第二个问题则是,假设有x种方案。从当前序列中取出若干个数使得和为k。那么答案加x。也就是说。第一个问题的推断根据是序列是否满足,第二个则是取出来的集合是否满足。而上述DP的方案事实上就是在选择集合中的元素,由于DP[i][j]表示i必须选,也就是在集合中存在。
那么到此,怎样推断一个序列是否是满足的呢:从左到右枚举序列当前位置的值,那么要求当前序列是否是满足的也就是求和能否到k,那么不可缺少的须要记录一下当前序列所能到达的和都有谁。至此。就能够用状压DP来解了。叙述一下二进制代表的意义:第一个1代表和为1。第二个1表示和为2……
反思一下程序写的时候的问题:没实用滚动数组,导致错了非常多次。因为这个题目的状态转移仅仅会向更大的状态值(也能够是自己)转移。所以能够不採用滚动数组,一维解决。
可是这样就须要额外注意一个问题。自己转移到自己的问题。因为这里理解的不是非常好。导致一直查不出来BUG。学习了。
const int MAXN = 21;
int dp[1 << MAXN]; int main()
{
int T, n, sum, Max;
RI(T);
FE(kase, 1, T)
{
RIII(n, sum, Max);
int Min = min(sum, Max);
int all = 1 << sum;
CLR(dp, 0); dp[0] = 1;
REP(i, n)
{
FED(j, all - 1, 0)
{
if (dp[j] == 0)
continue;
int x = dp[j];
for (int k = 1; k <= Min; k++)
{
int nxt = j | ((j << k) & (all - 1)) | (1 << (k - 1));
dp[nxt] += x;
if (dp[nxt] >= MOD)
dp[nxt] -= MOD;
}
if (Max - Min > 0)
dp[j] = (dp[j] + 1LL * (Max - Min) * x) % MOD;
}
}
int ans = 0;
FF(i, 1 << (sum - 1), all)
{
ans += dp[i];
if (ans >= MOD)
ans -= MOD;
}
WI(ans);
}
return 0;
}
const int MAXN = 21; int dp[1 << MAXN]; int main()
{
int T, n, sum, Max;
RI(T);
FE(kase, 1, T)
{
RIII(n, sum, Max);
int Min = min(sum, Max);
int all = 1 << (sum + 1);
CLR(dp, 0); dp[1] = 1;
REP(i, n)
{
FED(j, all - 1, 1)
{
if (dp[j] == 0)
continue;
int x = dp[j];
for (int k = 1; k <= Min; k++)
{
int nxt = j | ((j << k) & (all - 1));
dp[nxt] += x;
if (dp[nxt] >= MOD)
dp[nxt] -= MOD;
}
if (Max - Min > 0)
dp[j] = (dp[j] + 1LL * (Max - Min) * x) % MOD;
}
}
int ans = 0;
FF(i, 1 << sum, all)
{
ans += dp[i];
if (ans >= MOD)
ans -= MOD;
}
WI(ans);
}
return 0;
}
Our happy ending的更多相关文章
- 非技术1-学期总结&ending 2016
好久好久没写博客了,感觉动力都不足了--12月只发了一篇博客,好惭愧-- 今天是2016年最后一天,怎么能不写点东西呢!! 学期总结 大学中最关键一年的第一个学期,共4个月.前20天在学网络方面的,当 ...
- android: Incorrect line ending: found carriage return (\r) without corresponding newline (\n)
当报这种错误的时候:Incorrect line ending: found carriage return (\r) without corresponding newline (\n) 解决方法: ...
- BZOJ 3870: Our happy ending( 状压dp )
dp(i, s)表示考虑了前i个数后, 能取到的数的集合为s时的方案数.对于1~min(L, K)枚举更新, 剩下的直接乘就好了. 复杂度O(T*K*2^N)...好像有点大, 但是可以AC.... ...
- [HDU4906]Our happy ending
[HDU4906]Our happy ending 题目大意: 让你构造一个\(n(n\le20)\)个数的数列,其中每个数都为小于等于\(l(l\le10^9)\)的非负整数. 问你能构造出多少个这 ...
- How to Pronounce Ending T Clusters + Homophones — Baking!
How to Pronounce Ending T Clusters + Homophones — Baking! Share Tweet Share Tagged With: ARE Reducti ...
- Beginning and Ending the Speech
Beginning and Ending the Speech Just as musical plays need appropriate beginnings and endings, so do ...
- Every ending is just a new beginning.
Every ending is just a new beginning.每次结束都是新的开始.
- HDU 4906 Our happy ending (状压DP)
HDU 4906 Our happy ending pid=4906" style="">题目链接 题意:给定n个数字,每一个数字能够是0-l,要选当中一些数字.然 ...
- 解决php - Laravel rules preg_match(): No ending delimiter '/' found 问题
### 说明解决php - Laravel preg_match(): No ending delimiter '/' found 一.遇到问题的原因本正常添加如下 public function r ...
- AngularJs之九(ending......)
今天继续angularJs,但也是最后一篇关于它的了,基础部分差不多也就这些,后续有机会再写它的提升部分. 今天要写的也是一个基础的选择列表: 一:使用ng-options,数组进行循环. <d ...
随机推荐
- python爬虫入门一:爬虫基本原理
1. 什么是爬虫 爬虫就是请求网站并提取数据的自动化程序 2. 爬虫的基本流程 1)发送请求 通过HTTP库向目标站点发送请求,即发送一个Request. 请求可以包含额外的headers等信息,等待 ...
- LeetCode(118) Pascal's Triangle
题目 Given numRows, generate the first numRows of Pascal's triangle. For example, given numRows = 5, R ...
- cf 1016D
D. Vasya And The Matrix time limit per test 2 seconds memory limit per test 256 megabytes input stan ...
- sql存储过程打印图形
print '三角形' declare @a int set @a=1 while(@a<10) begin print replace(space(@a),' ','*') set @a=@a ...
- python数据类型小结
变量 变量是 为了存储程序 运算过程中的一些中间结果,为了方便日后调用. 变量的命名规则1.要有描述性2.变量名只能_,数字,字母组成,不可以是特殊字符(#)3.不能以中文为变量名4.不能以数字开头5 ...
- linux系统管理员 第五部分 1认识系统服务
linux系统管理员 一 认识系统服务 二认识与分析登录文件 三启动流程.模组管理与loader 四网络设定与备份策略 五软件的安装 源代码与tarball 六软件的安装rpm srpm与yum ...
- VS2010SP1修复补丁&Microsoft Visual Studio 2010 Service Pack 1
网上比较难找,官网找也容易找错,现在贴出来 补丁包下载地址:链接:https://pan.baidu.com/s/1_tFzXL6PaHiWk3JeRBw0ww 密码:z38k
- 【JavaScript 13—应用总结】:锁屏遮罩
导读:上次说了,当弹出登录框时,由于背景色和弹出框时一样的,这样子,其实比较难聚焦到底该操作哪一块.所以,如果,有了颜色的区分,那么通过屏幕遮罩的效果,就可以将我们希望要被处理的东西突出显示.也就达到 ...
- .NET重构(九):机房重构验收总结
导读:机房收费系统个人重构版,在寒假前,已经结束了.嗯,这一路的过程,也挺心酸的.结合师傅验收时的指导.建议,对这一段时间的学习,进行一个总结. 一.学习过程 这一阶段的学习,按照师傅给的建议是:由浅 ...
- linux的自启动服务脚本的(/etc/rc.d/init.d或者其链接/etc/init.d)
转载地址:http://www.cnblogs.com/diyunpeng/archive/2009/11/11/1600886.html Linux有自己一套完整的启动体系,抓住了linux启动的脉 ...