题目描述

小Z所在的城市有N个公交车站,排列在一条长(N-1)km的直线上,从左到右依次编号为1到N,相邻公交车站间的距离均为1km。 作为公交车线路的规划者,小Z调查了市民的需求,决定按下述规则设计线路:
1.设共K辆公交车,则1到K号站作为始发站,N-K+1到N号台作为终点站。
2.每个车站必须被一辆且仅一辆公交车经过(始发站和终点站也算被经过)。 
3.公交车只能从编号较小的站台驶往编号较大的站台。 
4.一辆公交车经过的相邻两个
站台间距离不得超过Pkm。 在最终设计线路之前,小Z想知道有多少种满足要求的方案。由于答案可能很大,你只需求出答案对30031取模的结果。

输入

仅一行包含三个正整数N K P,分别表示公交车站数,公交车数,相邻站台的距离限制。
N<=10^9,1<P<=10,K<N,1<K<=P

输出

仅包含一个整数,表示满足要求的方案数对30031取模的结果。

样例输入

样例一:10 3 3
样例二:5 2 3
样例三:10 2 4

样例输出

1
3
81


题解

状压dp+矩阵乘法

很容易想到以当前枚举位置下每辆车最后的出现位置为状态,即 $f[i][j]$ 表示 $i$ 个位置,每辆车最后的出现位置状态为 $j$ 的方案数。

那么考虑转移:如果某个车的位置是从左到右 $p$ 个中的第 $1$ 个,则必须移动这辆车;否则可以移动任意一辆车。

但是这样状态难以存下($A_p^k$)

仔细思考可以发现,每辆车都是一样的,因此没有顺序之分,状态数从排列变为了组合($C_p^k$),最多只有 $C_{10}^5=252$ 。

而且进一步可以通过dp的意义得到:状态中一定有一辆车在最后一个位置。因此最多只有 $C_9^4=126$ 。

按照这个思路容易想到矩阵乘法。

设二进制状态表示从左到右的 $p$ 个位置中,哪些位置是 $k$ 辆车的最后出现的位置。

那么初始状态和结束状态都可以看成前 $p-k$ 个位置为空,后 $k$ 个位置全有车。显然需要转移 $n-k$ 次。

因此首先预处理状态和转移,然后直接求矩阵的 $n-k$ 次方计算即可。

时间复杂度 $O((C_{p-1}^{k-1})^3\log n)$

#include <cstdio>
#include <cstring>
#include <algorithm>
#define mod 30031
using namespace std;
int c[1030] , w[1030] , v[130] , n;
struct data
{
int v[130][130];
data() {memset(v , 0 , sizeof(v));}
int *operator[](int a) {return v[a];}
data operator*(data &a)
{
data ans;
int i , j , k;
for(i = 1 ; i <= n ; i ++ )
for(j = 1 ; j <= n ; j ++ )
for(k = 1 ; k <= n ; k ++ )
ans[i][j] = (ans[i][j] + v[i][k] * a[k][j]) % mod;
return ans;
}
}A;
data pow(data x , int y)
{
data ans;
int i;
for(i = 1 ; i <= n ; i ++ ) ans[i][i] = 1;
while(y)
{
if(y & 1) ans = ans * x;
x = x * x , y >>= 1;
}
return ans;
}
int main()
{
int m , k , p , i , j;
scanf("%d%d%d" , &m , &k , &p);
for(i = 1 ; i < (1 << p) ; i ++ )
{
c[i] = c[i - (i & -i)] + 1;
if(c[i] == k && i & (1 << (p - 1))) w[i] = ++n , v[n] = i;
}
for(i = 1 ; i <= n ; i ++ )
{
if(v[i] & 1) A[i][w[(1 << (p - 1)) | (v[i] >> 1)]] = 1;
else
for(j = 0 ; j < p ; j ++ )
if(v[i] & (1 << j))
A[i][w[(1 << (p - 1)) | ((v[i] ^ (1 << j)) >> 1)]] = 1;
}
A = pow(A , m - k);
i = w[(1 << p) - (1 << (p - k))];
printf("%d\n" , A[i][i]);
return 0;
}

【bzoj2004】[Hnoi2010]Bus 公交线路 状压dp+矩阵乘法的更多相关文章

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

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

  2. [Bzoj2004][Hnoi2010]Bus 公交线路(状压dp&&矩阵加速)

    题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=2004 看了很多大佬的博客才理解了这道题,菜到安详QAQ 在不考虑优化的情况下,先推$dp ...

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

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

  4. 『公交线路 状压dp 矩阵乘法加速』

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

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

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

  6. BZOJ 2004 公交线路(状压DP+矩阵快速幂)

    注意到每个路线相邻车站的距离不超过K,也就是说我们可以对连续K个车站的状态进行状压. 然后状压DP一下,用矩阵快速幂加速运算即可. #include <stdio.h> #include ...

  7. BZOJ2004: [Hnoi2010]Bus 公交线路

    题目:http://www.lydsy.com/JudgeOnline/problem.php?id=2004 状压dp+矩阵乘法. f[i][s]表示从第i位至前面的i-k位,第i位必须取的状态. ...

  8. bzoj2004 [Hnoi2010]Bus 公交线路 矩阵快速幂+状压DP

    题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=2004 题解 如果 \(N\) 没有那么大,考虑把每一位分配给每一辆车. 假设已经分配到了第 \ ...

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

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

随机推荐

  1. Luogu P1802 5倍经验日_KEY

    题目传送门 ·背包 这可以说是一道背包的变形. 首先需要考虑到的是如何将ta转换为一个正常 的背包. 这些数据有一个让我们都十分不爽的地方就是有两个值. 所以我们就设置一个基准值,将失败的经验值当做基 ...

  2. 北京Uber优步司机奖励政策(2月1日)

    滴快车单单2.5倍,注册地址:http://www.udache.com/ 如何注册Uber司机(全国版最新最详细注册流程)/月入2万/不用抢单:http://www.cnblogs.com/mfry ...

  3. 北京Uber优步司机奖励政策(1月15日)

    滴快车单单2.5倍,注册地址:http://www.udache.com/ 如何注册Uber司机(全国版最新最详细注册流程)/月入2万/不用抢单:http://www.cnblogs.com/mfry ...

  4. Java:List判空的条件:List=null 和 List.size = 0

    当需要对一个LIst进行判空操作时我们可使用如下两个语句: if (list == null || list.size() == 0) {} if (list != null && l ...

  5. nio之netty5应用

    1.netty5和netty4的区别不是很大,但是与netty3差别还是有的.这里不介绍netty4,因为和netty5的方式都差不多.netty5的复杂性相对于netty3要多很多了.基本上架构都被 ...

  6. VMWare虚拟机下 centos network is unreachable 问题的解决

    vi /etc/sysconfig/network-scripts/ifcfg-eth0 DEVICE=eth0 BOOTPROTO=static BROADCAST=192.168.1.255 HW ...

  7. NSNull Crash处理 (NullSafe 的原理)

    问题场景 后端返回的数据中总会出现一些NSNull类型,当我们一处理程序就会崩溃,因此想到把返回的数据中的NSNull类型全部转换成@""空字符串 (1)原始的json串:后端返回 ...

  8. android 学习十四 探索安全性和权限

    1.部署安全性:应用程序必须使用数字证书才能安装到设备上. 2.执行期间的安全性:    2.1 使用独立进程    2.2 使用固定唯一用户ID    2.3  申明性权限模型   3数字证书   ...

  9. Weka java.lang.reflect.InvocationTargetException

    在用Weka导入数据的时候报 java.lang.reflect.InvocationTargetException 错误,Weka运行包没有给出详细的错误信息,无法查到. 直接调试Weka源码,发现 ...

  10. ConfigHelpers

    --默认值可以不传 local ConfigHelpers = {} --设置物体高亮 target:设置对象 isLigth:是否高亮 seeThrough:是否穿透(默认为true,穿透) sta ...