题目链接

  • 题意:

    输入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;
}

用dp[1]表示0的方法,事实上不好。由于3(11)和2(10)表示的意义是一样的,并且不含或者包括零(第一个一)没有什么意义
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. 非技术1-学期总结&ending 2016

    好久好久没写博客了,感觉动力都不足了--12月只发了一篇博客,好惭愧-- 今天是2016年最后一天,怎么能不写点东西呢!! 学期总结 大学中最关键一年的第一个学期,共4个月.前20天在学网络方面的,当 ...

  2. android: Incorrect line ending: found carriage return (\r) without corresponding newline (\n)

    当报这种错误的时候:Incorrect line ending: found carriage return (\r) without corresponding newline (\n) 解决方法: ...

  3. BZOJ 3870: Our happy ending( 状压dp )

    dp(i, s)表示考虑了前i个数后, 能取到的数的集合为s时的方案数.对于1~min(L, K)枚举更新, 剩下的直接乘就好了. 复杂度O(T*K*2^N)...好像有点大, 但是可以AC.... ...

  4. [HDU4906]Our happy ending

    [HDU4906]Our happy ending 题目大意: 让你构造一个\(n(n\le20)\)个数的数列,其中每个数都为小于等于\(l(l\le10^9)\)的非负整数. 问你能构造出多少个这 ...

  5. How to Pronounce Ending T Clusters + Homophones — Baking!

    How to Pronounce Ending T Clusters + Homophones — Baking! Share Tweet Share Tagged With: ARE Reducti ...

  6. Beginning and Ending the Speech

    Beginning and Ending the Speech Just as musical plays need appropriate beginnings and endings, so do ...

  7. Every ending is just a new beginning.

    Every ending is just a new beginning.每次结束都是新的开始.

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

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

  9. 解决php - Laravel rules preg_match(): No ending delimiter '/' found 问题

    ### 说明解决php - Laravel preg_match(): No ending delimiter '/' found 一.遇到问题的原因本正常添加如下 public function r ...

  10. AngularJs之九(ending......)

    今天继续angularJs,但也是最后一篇关于它的了,基础部分差不多也就这些,后续有机会再写它的提升部分. 今天要写的也是一个基础的选择列表: 一:使用ng-options,数组进行循环. <d ...

随机推荐

  1. git 常用命令及虚拟机服务器仓库搭建

    $ git config --global user.email "you@example.com" $ git config --global user.name "Y ...

  2. 咕咕咕,skkyk的博客生活从此开始了

    2019-5-9 咕咕咕,skkyk的博客生活从此开始了 我是划水时长两个半小时的个人OIer skkyk,我喜欢打表,暴零,骗分,瞎搞(律师函警告); 2019-6-14 中考结束的第二天 我们苦逼 ...

  3. linux下防火墙iptables原理及使用

    iptables简介 netfilter/iptables(简称为iptables)组成Linux平台下的包过滤防火墙,与大多数的Linux软件一样,这个包过滤防火墙是免费的,它可以代替昂贵的商业防火 ...

  4. spring-cloud-sleuth 学习资源

    https://www.baeldung.com/spring-cloud-sleuth-single-application https://howtodoinjava.com/spring-clo ...

  5. Java-使用哈希码比较对象的值

    在一些特殊的情况下使用 package com.tj; import java.io.File; public class MyHash { public static void main(Strin ...

  6. hdu3594 Cactus

    仙人掌入门简单题. 先看一篇文档. #include <iostream> #include <cstring> #include <cstdio> using n ...

  7. VC调试入门

    概述调试是一个程序员最基本的技能,其重要性甚至超过学习一门语言.不会调试的程序员就意味着他即使会一门语言,却不能编制出任何好的软件.这里我简要的根据自己的经验列出调试中比较常用的技巧,希望对大家有用. ...

  8. 在xcode上把你的app多语言国际化(NSLocalizedString)

    1.到project->info->localizations   下面的加号,添加你需要的语言 千万不要删除  base 否虽然我不知道有什么用,我是删了整个storyboard没了,很 ...

  9. vim第五章 命令行模式

    vim第五章命令行模式 技巧 27 结识vim的命令行模式 在命令行模式中执行的命令有被称作ex命令    在按/调出查找提示符或者<C-r>=访问表示寄存器时 命令行模式也被激活     ...

  10. hdu2022

    #include <stdio.h> #include <math.h> #define here puts("go,go,go!\n") int main ...