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. Archlinux无线联网教程

    本人是学生党,故对于有线方式不甚了解,学校里一般使用mentohust用动态IP方式联网,或者直接连接wifi,这里介绍无线联网的一些方式,主要包括公共wifi和带有WEP或者WPA或者WPA2PSK ...

  2. JAVA接口基础知识总结

    1:是用关键字interface定义的. 2:接口中包含的成员,最常见的有全局常量.抽象方法. 注意:接口中的成员都有固定的修饰符. 成员变量:public static final     成员方法 ...

  3. python 操作MongoDB

    安装MongoDB 启动数据库:安装完成指定数据库存放路径 mongod.exe --dbpath c:\data\db进入目录后运行mongo.exe 成功 创建数据库 > use mydb ...

  4. css精简命名

    想写写前言啥的,发现自己是前言无能星人. 简单吐吐槽好了,来到新公司,接手公司之前的项目,我想着也就是改改bug,慢慢来吧,粗略看了看这个项目的代码,目前仅看了html和css样式的,忍不住吐血三升. ...

  5. SpringCloud的部署模型

    http://www.th7.cn/Program/java/201608/919853.shtml

  6. python网络爬虫与信息提取 学习笔记day2

    Day2: 查看robots协议: 查看京东的robots协议 查看百度的robots协议,可以看到百度拒绝了搜狗的爬虫233 爬取京东商品页面相关信息: import requests url = ...

  7. 模板引擎Jade详解

    有用的符号: | 竖杠后的字符会被原样输出 · 点表示下一级的所有字符都会被原样输出,不再被识别.(就是|的升级版,实现批量) include 表示引用外部文件 短杠说明后面跟着的字符只是一段代码(与 ...

  8. JavaScript简单重写构造器的原型

    //简单重写原型对象: //一个构造函数Person function Person(){ } //重写Person的原型 //把Person的原型赋值给一个新的对象 是我们重写的过程 Person. ...

  9. uvalive 3213 Ancient Cipher

    https://vjudge.net/problem/UVALive-3213 题意: 输入两个字符串,问是否可以由第一个字符串的每个字符一一映射得到第二个字符串,字符是可以随意移动的. 思路: 统计 ...

  10. hdu-2141 Can you find it?---暴力+二分

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=2141 题目大意: 给ABC三个数组,给一个X,求是否存在Ai+Bj+Ck = X 思路: 等式转化成 ...