博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Codeforces 757D - Felicity's Big Secret Revealed
阅读量:4338 次
发布时间:2019-06-07

本文共 1208 字,大约阅读时间需要 4 分钟。

题目大意:给你一串有n(n<=75)个0或1组成的串,让你划最多n+1条分割线,第一条分割线的前面和最后一条分割线的后面

不算一段。设剩下的段里面的最大值为max,若1-max都在这些段里面出现过则算一个有效划分,问你总共有多少有效划分,

答案对1e9+7取模。

 

写的时候感觉是个dp,单就是想不出来,看了题解说是状态压缩dp,把出现过哪些数字当做状态,这样才写出来的QAQ。

 

思路:因为n<=75,我们列一下,最大值肯定不会超过20,这样我们就能状态压缩了。

dp[ i ][ j ]表示,最后一条划分线在第 i 个数后面,状态为 j 的划分数。这样我们就可以枚举划分的第一个数,

再枚举这个段的长度k,如果这个段对应的十进制的值为w,那么状态转移方程为 dp[ i + k -1 ] [ j | ( 1 << ( w - 1 ) ) ]+=dp[ i - 1 ][ j ];

 

#include
#define ll long longusing namespace std;const int N=80;const int M=20;const ll mod=1e9+7;int dp[N][(1<
>n; for(int i=1;i<=n;i++) scanf("%1d",&a[i]); for(int i=0;i<=n;i++) dp[i][0]=1; for(int i=1;i<=n;i++) { for(int j=0;j
n) break; int w=work(i,i+k,k+1); if(w>20) break;//这里不判断会RE if(w>=1) dp[i+k][j|(1<<(w-1))]=(dp[i+k][j|(1<<(w-1))]+dp[i-1][j])%mod; } } } int ans=0; for(int i=1;i<=n;i++) { int now=1; int p=0; for(int j=1;j<=20;j++) { p+=now; ans=(ans+dp[i][p])%mod; now*=2; } } cout<
<
View Code

 

转载于:https://www.cnblogs.com/CJLHY/p/7391313.html

你可能感兴趣的文章
Equivalent Strings
查看>>
flume handler
查看>>
收藏其他博客园主写的代码,学习加自用。先表示感谢!!!
查看>>
H5 表单标签
查看>>
su 与 su - 区别
查看>>
C语言编程-9_4 字符统计
查看>>
在webconfig中写好连接后,在程序中如何调用?
查看>>
限制用户不能删除SharePoint列表中的条目(项目)
查看>>
feign调用spring clound eureka 注册中心服务
查看>>
ZT:Linux上安装JDK,最准确
查看>>
LimeJS指南3
查看>>
关于C++ const成员的一些细节
查看>>
《代码大全》学习摘要(五)软件构建中的设计(下)
查看>>
C#检测驱动是否安装的问题
查看>>
web-4. 装饰页面的图像
查看>>
微信测试账户
查看>>
Android ListView上拉获取下一页
查看>>
算法练习题
查看>>
学习使用Django一 安装虚拟环境
查看>>
Hibernate视频学习笔记(8)Lazy策略
查看>>