hdu 4906 状压dp
2016-05-31 00:03
363 查看
题意:给出n,k<=20,L<=10^9 问能不能通过不大于L的数组成一个含n个数的序列使得能从这个序列中挑出几个数的和为k,求满足条件序列的个数
题解:看到k<20可以用sum的状态做状压dp的状态
状态转移方程next=(1<<(p-1))|j|((j<<p)&SIZE); dp[next]=(dp[next]+v)%mod;
题解:看到k<20可以用sum的状态做状压dp的状态
状态转移方程next=(1<<(p-1))|j|((j<<p)&SIZE); dp[next]=(dp[next]+v)%mod;
#include<cmath> #include<cstdio> #include<cstring> #include<algorithm> #define ll __int64 using namespace std; const ll mod=1e9+7; ll dp[1<<21],v; int main() { int T,n,k,l,MIN,SIZE,i,j,p; scanf("%d",&T); while(T--){ scanf("%d%d%d",&n,&k,&l); memset(dp,0,sizeof(dp)); dp[0]=1;//赋初值不然没法启动 SIZE=(1<<k)-1;//最大状态 ll MIN=min(l,k);//因为大于k的值是没用的可以在后面直接加上去 for(i=1;i<=n;i++){//因为要加n个数这里枚举次数 for(j=SIZE;j>=0;j--){//倒着枚举状态是类似背包一样防止重复加 v=dp[j]; if(v==0)continue; for(p=1;p<=MIN;p++){ int next=(1<<(p-1))|j|((j<<p)&SIZE);//加上数p后的状态1.p本身2.j本身3.j的每一位加上p后的状态 dp[next]=(dp[next]+v)%mod; } if(k<l)dp[j]=(dp[j]+(ll)v*(l-k))%mod;//剩下部分直接加上去不知道为什么看有些blog没限制条件答案也是对的 }//是数据太弱吗 } ll ans=0; for(i=0;i<=SIZE;i++) if(i&(1<<(k-1))) (ans+=dp[i])%=mod; printf("%I64d\n",ans); } return 0; }
相关文章推荐
- MongoDB教程
- 接口测试初学者心得——从1 往后
- Objective-C ---UIButton (梳理整理)
- Wamp伪静态开启配置
- mybatis配置oracle时,自己遇到问题
- [Java]文档及javadoc使用
- Python在Facebook的应用情况
- 堡垒机-麒麟开源堡垒机后台进程列表及DEBUG说明
- 为什么用自助建站系统搭建网站?
- 正向代理和反向代理
- android开发之java代码中字符串对比忽略大小写。java程序员必回,可用来比对验证码等问题
- Android开发之 。。各种Adapter的用法
- MD5加密,java String 转变成MD5 String 详细代码,工具类Android开发必备
- android开发之splash闪屏页判断是否第一次进入app代码
- Android Studio或者Eclipse中的最常用的快捷键,最简单的,部分不适用eclipse
- android开发之 listview中的item去掉分割线 隐藏分割线
- String Matching in the legend
- Android手机点击查看手机电量Demo,android开发小项目Test 利用广播
- String,StringBuffer与StringBuilder的区别??
- 【Linux利用远程SSH连接】SecureCRT中文出现乱码解决办法 Linux服务器技术