Description

小Z所在的城市有N个公交车站,排列在一条长(N-1)km的直线上,从左到右依次编号为1到N,相邻公交车站间的距

离均为1km。 作为公交车线路的规划者,小Z调查了市民的需求,决定按下述规则设计线路:

1.设共K辆公交车,则1到K号站作为始发站,N-K+1到N号台作为终点站。

2.每个车站必须被一辆且仅一辆公交车经过(始发站和

终点站也算被经过)。

3.公交车只能从编号较小的站台驶往编号较大的站台。

4.一辆公交车经过的相邻两个

站台间距离不得超过Pkm。 在最终设计线路之前,小Z想知道有多少种满足要求的方案。由于答案可能很大,你只

需求出答案对30031取模的结果。

解题报告:

用时:2h30min,1AC

这题拿着毫无办法,只能请教大佬,原来是矩阵优化DP,这个DP也是非常的诡异,首先我们要保证移动不超过P,所以我们以P为单位做矩阵,然后P很小可以状压,所以我们想办法DP,可以设\(f[i][j]\)表示\(i\)这个位置起,后面P个站的是否有车的状态,1表示有,0表示没有,转移方程类似于:

\(f[i][j]+=f[i-1][k]\) 条件是\(j\)相比\(k\)只动了一辆车的先后顺序。

但是没这么简单,因为对于\((1,3),(2,4)\)这两个状态既可以从\((1,3),(2)\)转移来,也可以从\((1),(2,4)\)转移来,所以方案会算重,所以要强制要求只有一辆车可以动,这里强制只能动 \(i\),也就是说这个例子中只有 \(1\) 可以移动,就没问题了,因为每次只移动一位且转移相同,直接丢到矩阵里做n-k次即可,然后辅助矩阵的\((i,j)\)表示i这个状态可以转移到j,所以合法的话我们就赋值为1,对于\(i\)是否能转移到\(j\)的\(check\),就是相当于\(i\)整体右移一位,并且除了第P位,其他位置要相同,只有多出来的位置可以不同.

#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <cmath>
#define RG register
#define il inline
#define iter iterator
#define Max(a,b) ((a)>(b)?(a):(b))
#define Min(a,b) ((a)<(b)?(a):(b))
using namespace std;
const int mod=30031;
int n,m,p,f[233],cnt=0;
void dfs(int dep,int tot,int sum){
if(sum==m){
f[++cnt]=tot;
return ;
}
if(dep==p+1)return ;
dfs(dep+1,tot+(1<<(p-dep)),sum+1);
dfs(dep+1,tot,sum);
}
struct mat{
int a[141][141];
mat(){memset(a,0,sizeof(a));}
mat operator *(const mat &pr)const{
mat tmp;
for(int i=1;i<=cnt;i++)
for(int j=1;j<=cnt;j++)
for(int k=1;k<=cnt;k++){
tmp.a[i][j]+=a[i][k]*pr.a[k][j]%mod;
if(tmp.a[i][j]>=mod)tmp.a[i][j]-=mod;
}
return tmp;
}
};
bool check(int x,int y){
int tmp=(x-(1<<(p-1)))<<1;
y^=tmp;if(y==(y&(-y)))return true;
return false;
}
void work()
{
scanf("%d%d%d",&n,&m,&p);
dfs(2,1<<(p-1),1);
mat T;
for(int i=1;i<=cnt;i++)
for(int j=1;j<=cnt;j++)
if(check(f[i],f[j]))T.a[i][j]=1;
mat S;
for(int i=1;i<=cnt;i++)S.a[i][i]=1;
n-=m;
while(n){
if(n&1)S=S*T;
T=T*T;n>>=1;
}
printf("%d\n",S.a[1][1]);
//为什么答案是这个?因为我的dfs顺序是这样的啊=.=
}
int main()
{
work();
return 0;
}

bzoj 2004: [Hnoi2010]Bus 公交线路的更多相关文章

  1. [BZOJ 2004] [Hnoi2010] Bus 公交线路 【状压DP + 矩阵乘法】

    题目链接: BZOJ - 2004 题目分析 看到题目完全不会..于是立即看神犇们的题解. 由于 p<=10 ,所以想到是使用状压.将每个连续的 p 个位置压缩成一个 p 位 2 进制数,其中共 ...

  2. BZOJ 2004: [Hnoi2010]Bus 公交线路 [DP 状压 矩阵乘法]

    传送门 题意: $n$个公交站点,$k$辆车,$1...k$是起始站,$n-k+1..n$是终点站 每个站只能被一辆车停靠一次 每辆车相邻两个停靠位置不能超过$p$ 求方案数 $n \le 10^9, ...

  3. 【BZOJ】2004: [Hnoi2010]Bus 公交线路 状压DP+矩阵快速幂

    [题意]n个点等距排列在长度为n-1的直线上,初始点1~k都有一辆公车,每辆公车都需要一些停靠点,每个点至多只能被一辆公车停靠,且每辆公车相邻两个停靠点的距离至多为p,所有公车最后会停在n-k+1~n ...

  4. 【BZOJ2004】[HNOI2010]Bus 公交线路

    [BZOJ2004][HNOI2010]Bus 公交线路 题面 bzoj 洛谷 题解 $N$特别大$P,K$特别小,一看就是矩阵快速幂+状压 设$f[S]$表示公交车状态为$S$的方案数 这是什么意思 ...

  5. 【BZOJ2004】[Hnoi2010]Bus 公交线路 状压+矩阵乘法

    [BZOJ2004][Hnoi2010]Bus 公交线路 Description 小Z所在的城市有N个公交车站,排列在一条长(N-1)km的直线上,从左到右依次编号为1到N,相邻公交车站间的距离均为1 ...

  6. 【BZOJ 2004】: [Hnoi2010]Bus 公交线路

    题目链接: TP 题解:   所以说,超显眼的数据范围啊. 很显然我们对于每个P的区间都是要有k个站被bus停留,然后考虑转移的话应该是把这k个站里的某个bus往前走,那么转移也很显然了,n的范围很大 ...

  7. BZOJ2004:[HNOI2010]Bus 公交线路(状压DP,矩阵乘法)

    Description 小Z所在的城市有N个公交车站,排列在一条长(N-1)km的直线上,从左到右依次编号为1到N,相邻公交车站间的距离均为1km. 作为公交车线路的规划者,小Z调查了市民的需求,决定 ...

  8. 【bzoj2004】[Hnoi2010]Bus 公交线路 状压dp+矩阵乘法

    题目描述 小Z所在的城市有N个公交车站,排列在一条长(N-1)km的直线上,从左到右依次编号为1到N,相邻公交车站间的距离均为1km. 作为公交车线路的规划者,小Z调查了市民的需求,决定按下述规则设计 ...

  9. [bzoj2004] [洛谷P3204] [Hnoi2010] Bus 公交线路

    Description 小Z所在的城市有N个公交车站,排列在一条长(N-1)km的直线上,从左到右依次编号为1到N,相邻公交车站间的距 离均为1km. 作为公交车线路的规划者,小Z调查了市民的需求,决 ...

随机推荐

  1. 2017-2018-1 我爱学Java 第三周 作业

    Team Presentation 团队展示 队员学号 队名 团队项目描述 队员风采 团队首次合照 团队的特色描述 团队初步合作 前两周合作过程中的优缺点 如何改进 团队选题 确立,建立和初步熟悉团队 ...

  2. php的set_time_limit()函数

    set_time_limit(0); 括号里边的数字是执行时间,如果为零说明永久执行直到程序结束,如果为大于零的数字,则不管程序是否执行完成,到了设定的秒数,程序结束. 一个简单的例子,在网页里显示1 ...

  3. Full-Stack-Fundation-Udacity------Lesson 1 Working with CRUD

    因为手头在做一个项目,我负责后台,就顺带快进学习Udacity上一个水课(?):Full Stack Foundation.上课的好像是个印度小哥(?),按1.5倍速听讲话还是有点逗的.废话不多说,进 ...

  4. CentOS 7 Redis安装配置

    1.获取Redis压缩包: wget http:.tar.gz 2.解压测试: mv 到 /usr/local/ tar .tar cd redis 3.使用make测试编译: make 这里可能会出 ...

  5. 零基础大数据入门教程:Java调用阿里云短信通道服务

    这里我们使用SpringBoot 来调用阿里通信的服务. 阿里通信,双11.收到短信,日发送达6亿条.保障力度非常高. 使用的步骤: 1.1. 第一步:需要开通账户 1.2. 第二步:阅读接口文档 1 ...

  6. eclipse版本对应的jdk版本

    Installing Eclipse is relatively easy, but does involve a few steps and software from at least two d ...

  7. Window7系统下安装jdk

    根据电脑的操作系统下载相对于的jdk版本(32位或64位),我安装的是:java_jdk1.7 [计算机]——[属性]——[高级系统设置]——高级——[环境变量] 系统变量——>新建JAVA_H ...

  8. SourceTree 01 - git 客户端介绍

    SourceTree - git客户端介绍 SourceTree系列第1篇 --->> SourceTree 01 - git 客户端介绍(http://www.cnblogs.com/g ...

  9. Android:CheckBox控件

    1)ChexkBox继承自CompoundButton组件: 2)isChecked()--确定是否选中:setChecked(bool checked)--设置选中或取消选中: 3)监听事件:Com ...

  10. [LeetCode] Student Attendance Record II 学生出勤记录之二

    Given a positive integer n, return the number of all possible attendance records with length n, whic ...