博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【BZOJ】2004: [Hnoi2010]Bus 公交线路 状压DP+矩阵快速幂
阅读量:7013 次
发布时间:2019-06-28

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

【题意】n个点等距排列在长度为n-1的直线上,初始点1~k都有一辆公车,每辆公车都需要一些停靠点,每个点至多只能被一辆公车停靠,且每辆公车相邻两个停靠点的距离至多为p,所有公车最后会停在n-k+1~n。给定n,k,p,求满足要求的方案数%30031。n<=10^9,k<=p<=10

【算法】状压DP+矩阵快速幂

【题解】开始没看到p<=10,其实很显然p>k的话第一车就不满足要求了。考虑相邻停靠点没有关键信息,只能状压。

因为车都是从头开到尾的,所以直接考虑i~i-p+1的公车停靠状态就行了(i-p和i的距离为p,也就是必须跳到i,因此考虑i-p没有意义)。

设$f[i][S]$表示考虑第i个位置(最快的车可能到i),i~i-p+1的公车停靠状态为S的方案数,并且强制S的最低位为1(从前往后从低到高)。

$$f[i][S]=\sum f[i-1][S']$$

将S右移一位,然后枚举0~p中没有1的位置插入一个1得到的就是合法的S‘,然后把所有状态放在矩阵中就可以快速幂n-k次了。

注意到S是有效状态当且仅当S中含有恰好k个1,所以预处理合法状态数是C(p,k)的,这样复杂度就可以保证了。

总复杂度O(C(p,k)^3*log n)。

#include
#include
#include
using namespace std;const int N=520,MOD=30031;int n,k,p,tot,c[N][N],q[N*2],A[N][N],ANS[N][N];void multply(int a[N][N],int b[N][N]){ for(int i=1;i<=tot;i++){ for(int j=1;j<=tot;j++){ c[i][j]=0; for(int k=1;k<=tot;k++){ c[i][j]=(c[i][j]+a[i][k]*b[k][j])%MOD; } } } for(int i=1;i<=tot;i++)for(int j=1;j<=tot;j++)b[i][j]=c[i][j];}int main(){ scanf("%d%d%d",&n,&k,&p); for(int S=0;S<(1<
>1; for(int i=0;i
<
<
<
>=1; } s=(1<
View Code

 

转载于:https://www.cnblogs.com/onioncyc/p/8783513.html

你可能感兴趣的文章
没有服务台,就没有ITSM
查看>>
加点自已内容的新内核下L7-FILTER的应用实例!
查看>>
不要返回null之EmptyFactory
查看>>
Visual Studio 11 Beta新特性(一):安装VS11
查看>>
QQ-weiyun(微云)-云储存
查看>>
微信公众帐号开发教程第3篇-开发模式启用及接口配置(转)
查看>>
第 12 章 Other Web Server
查看>>
.NET项目web自动化测试实战——Selenium 2.0
查看>>
[LeetCode] Split Concatenated Strings 分割串联字符串
查看>>
Asp.Net SignalR - 持久连接类
查看>>
11.8. NAT
查看>>
PowerShell调用jira rest api实现jira统计自动化
查看>>
Git 时间,将代码托管到GitHub 上
查看>>
火车票秒杀攻略
查看>>
关于Asp.Net中FileUpload控件属性PostedFile.ContentType的提示
查看>>
Laravel5做权限管理
查看>>
Spring 通过Java代码装配bean
查看>>
架构重构-好文分享
查看>>
使用shell批量生成数据整合式迁移的脚本
查看>>
[20151021]理解dbms_xplan.display_cursor的format参数all.txt
查看>>