Our happy ending

Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)
Total Submission(s): 570    Accepted Submission(s): 183

Problem Description
There is an old country and the king fell in love with a devil. The devil always asks the king to do some crazy things. Although the king used to be wise and beloved by his people. Now he is just like a boy in love and can’t refuse any request from the devil. Also, this devil is looking like a very cute Loli.

Y*wan still remember the day he first meets the devil. Now everything is done and the devil is gone. Y*wan feel very sad and suicide.

You feel guilty after killing so many loli, so you suicide too.

Nobody survive in this silly story, but there is still some hope, because this is just a silly background story during one programming contest!

And the last problem is:

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.

You should output the result modulo 10^9+7.

 
Input
The first line contains an integer T, denoting the number of the test cases.
For each test case, the first line contains 3 integers n, k, L.

T<=20, n,k<=20 , 0<=L<=10^9.

 
Output
For each cases, output the answer in a single line.
 
Sample Input
1
2 2 2
 
Sample Output
6
 
题意:求n个数组成的有序数列,满足存在一个子数列和为k,且每个数在[0,l]的范围内,这样的有序数列有多少个?

递推实现 f[i][j]表示前i个数能够表示j状态的方案数,其中j为最多20位的二进制,每一二进制位表示‘和’为该位置是否达到,比如第20位二进制位若为1,表示的就是前i个数和有达到20,这20位表示的就是一个状态。

从j状态向上推,若该位置取k,则 需要更新的状态为 j | j<<k | 1<<(k-1) 注意包括0位置

可以用一维数组实现滚动数组优化

复杂度理论上高达O(n^2*2^k)会超时,但是要注意到很大部分f[i][j]=0,加上这个优化瞬间快了10倍多

    中间的递推过程从标程中照搬下来了,惭愧!

#include "cstdio"
#include "cstring"
#define min(x,y) (x>y?y:x) #define MOD 1000000007 int f[];
int n,k,l;
int main()
{
int tt;
scanf("%d",&tt);
while(tt--)
{
memset(f,,sizeof(f));
scanf("%d%d%d",&n,&k,&l);
int ms=(<<k)-;
long long ans=; for(int j=; j<=min(l,k); j++)
f[<<(j-)]=;
if(l>k) f[]=(f[]+l-k)%MOD; for(int i=; i<n; i++)
for(int s=ms; s>=; s--) //从大到小 避免重复计算
if(f[s]>) //没加这句20s+ 加了就1286ms
{
long long tmp=f[s]; //滚动数组压缩 发现滚动数组都不需要了 !
for(int j=; j<=min(l,k); j++) //f[i][s] 插入j=0的情况直接保存给 f[i+1][s]
{
int ns=(s|(s<<j)|(<<(j-)))&ms; //包括从0处向右推j位
f[ns]=(f[ns]+tmp)%MOD;
}
if(l>k)
f[s]=(f[s]+(l-k)*tmp%MOD)%MOD;
} for(int s=; s<=ms; s++)
if(s&(<<(k-)))
ans=(ans+f[s])%MOD; printf("%lld\n",ans);
}
return ;
}

之前看解题报告写的

    开了二维数组,画蛇添足的加了个快速幂和组合 =.=  时间20s+

超时代码:

#include "cstdio"
#include "cstring"
#define min(x,y) (x>y?y:x)
#define MOD 1000000007
int f[][],c[][];
int n,k,l;
inline long long pow(long long a, long long b)
{
long long ret=,tmp=a%MOD;
while(b)
{
if(b&) ret=(ret*tmp)%MOD;
tmp=(tmp*tmp)%MOD;
b>>=;
}
return ret;
}
int main()
{
for(int i=; i<=; i++)
for(int j=; j<=i; j++)
if(j>) c[i][j]=c[i-][j]+c[i-][j-];
else c[i][j]=;
int tt;
scanf("%d",&tt);
while(tt--)
{
memset(f,,sizeof(f));
scanf("%d%d%d",&n,&k,&l);
int ms=(<<k)-;
for(int j=; j<=min(l,k); j++)
f[][<<(j-)]=;
for(int i=; i<n; i++)
for(int j=; j<=min(l,k); j++)
for(int s=; s<=ms; s++)
{
f[i+][(s|(s<<j)|(<<(j-)))&ms]+=f[i][s];
f[i+][(s|(s<<j)|(<<(j-)))&ms]%=MOD;
}
long long ans=;
if(l<=k)
{
for(int s=; s<=ms; s++)
if(s&(<<(k-)))
ans=(ans+f[n][s])%MOD;
}
else
{
for(int i=; i<=n; i++)
for(int s=; s<=ms; s++)
if(s&(<<(k-)))
ans=(ans+((long long)f[i][s]*(long long)c[n][i])%MOD*pow(l-k,n-i))%MOD;
}
printf("%lld\n",ans);
}
return ;
}

HDU 4906 状态压缩dp的更多相关文章

  1. HDU 1074 (状态压缩DP)

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=1074 题目大意:有N个作业(N<=15),每个作业需耗时,有一个截止期限.超期多少天就要扣多少 ...

  2. HDU 3341 状态压缩DP+AC自动机

    题目大意: 调整基因的顺序,希望使得最后得到的基因包含有最多的匹配串基因,使得所能达到的智商最高 这里很明显要用状态压缩当前AC自动机上点使用了基因的情况所能达到的最优状态 我最开始对于状态的保存是, ...

  3. hdu 4284 状态压缩dp

    题意: 有N 个点的无向图,要去其中 h个地点做事,做事需要先办理护照,之后可以挣一定数量的钱,知道了一开始有的总钱数,和 一些城市之间           道路的花费,问可不可以在 指定的 h 个城 ...

  4. hdu 2167 状态压缩dp

    /* 状态转移方程:dp[i][j]=Max(dp[i][j],dp[i-1][k]+sum[i][j]); */ #include<stdio.h> #include<string ...

  5. HDU 4856 (状态压缩DP+TSP)

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=4856 题目大意:有一个迷宫.迷宫里有些隧道,每个隧道有起点和终点,在隧道里不耗时.出隧道就耗时,你的 ...

  6. HDU 4640 状态压缩DP 未写完

    原题链接:http://acm.hdu.edu.cn/showproblem.php?pid=4640 解题思路: 首先用一个简单的2^n*n的dp可以求出一个人访问一个给定状态的最小花费,因为这i个 ...

  7. 2016"百度之星" - 初赛(Astar Round2A)1002 / HDU 5691 状态压缩DP

    Sitting in Line Problem Description   度度熊是他同时代中最伟大的数学家,一切数字都要听命于他.现在,又到了度度熊和他的数字仆人们玩排排坐游戏的时候了.游戏的规则十 ...

  8. HDU 5067 (状态压缩DP+TSP)

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5067 题目大意:蓝翔挖掘机挖石子.把地图上所有石子都运回起点,问最少耗时. 解题思路: 首先得YY出 ...

  9. hdu 4539(状态压缩dp)

    题意:曼哈顿距离是指:|x1-x2|+|y1-y2|,只要知道这个概念题意就懂了. 分析:这道题与前面做的几道题有所不同,因为当前行不仅与前一行有关,而且与前两行有关,所以我们开数组的时候还要记录前两 ...

随机推荐

  1. C#基础原理拾遗——面试都爱问的委托和事件(纠正)

    这篇博客是我昨天写的,文中的观点有些问题,后经过网友留言和个人学习发现错误,原文还是保留,更改补在后面,不怕贻笑大方,唯恐误人子弟.不知道还能不能放在首页,让被误导的同学再被反误导一次. 一.原文 几 ...

  2. Careercup - Facebook面试题 - 5179916190482432

    2014-05-01 00:45 题目链接 原题: input [,,,] output [,,,] Multiply all fields except it's own position. Res ...

  3. [转载+原创]Emgu CV on C# (二) —— Emgu CV on 灰度化

    本文主要对彩色图片灰度化的方法及其实现过程进行总结,最终给出Emgu CV实现的代码. 一.灰度化原理及数学实现(转载自——<图像灰度化方法总结及其VC实现> 该篇文章使用opencv实现 ...

  4. BAT CMD 批处理文件脚本 -2

    http://checheng1988.blog.51cto.com/4725808/1090733 在很多windows程序中会见到很多用扩展名为.bat和.cmd结尾的文件,那么这些文件能干什么呢 ...

  5. NYOJ-469 擅长排列的小明 II AC 分类: NYOJ 2014-01-02 22:19 159人阅读 评论(0) 收藏

    最初的第一印象是和组合数一个性质的题目.所以用了回溯法,结果,你懂的... #include<stdio.h> #include<math.h> void dfs(int n, ...

  6. 堆栈中的EIP EBP ESP

    EIP,EBP,ESP都是系统的寄存器,里面存的都是些地址.  为什么要说这三个指针,是因为我们系统中栈的实现上离不开他们三个.  我们DC上讲过栈的数据结构,主要有以下特点:  后进先处.(这个强调 ...

  7. 【二叉树遍历模版】前序遍历&&中序遍历&&后序遍历&&层次遍历&&Root->Right->Left遍历

    [二叉树遍历模版]前序遍历     1.递归实现 test.cpp: 12345678910111213141516171819202122232425262728293031323334353637 ...

  8. 暑假集训单切赛第二场 UVA 11988 Broken Keyboard (a.k.a. Beiju Text)(字符串处理)

    一开始不懂啊,什么Home键,什么End键,还以为相当于括号,[]里的东西先打印出来呢.后来果断百度了一下. 悲催啊... 题意:给定一个字符串,内部含有'['和']'光标转移指令,'['代表光标移向 ...

  9. Jenkins使用

    1. Jenkins工作流程: ①配置代码源,从代码源(如svn.git等)拉取代码,放入工作区 ②构建触发器(引发构建的条件,比如一定周期.代码提交更改等),从而能自动的进行构建 ③构建,选择构建的 ...

  10. this指针指向的彻底理解

    首先必须要说的是,this的指向在函数定义的时候是确定不了的,只有函数执行的时候才能确定this到底指向谁,实际上this的最终指向的是那个调用它的对象(这句话有些问题,后面会解释为什么会有问题,虽然 ...