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

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

题意:

$n$个公交站点,$k$辆车,$1...k$是起始站,$n-k+1..n$是终点站

每个站只能被一辆车停靠一次

每辆车相邻两个停靠位置不能超过$p$

求方案数

$n \le 10^9,\ p \le 8,\ k \le 10$


 

思考过程中遇到的主要问题是“所有车是同时前进的”,既不能单独考虑一辆车又没法考虑前面的车队后面的影响

正确的做法是同时考虑所有车

每$p$个位置一定每辆车各停一次

$f[i][s]$表示当前在站点$i$,且$i$有车,$s$为车停靠状态

强制规定最靠左(即$i$处)的车先走避免重复

发现状态形成一个图,建立状态之间的邻接矩阵,就可以矩乘来算了

 

状态最多有$\binom{9}{5}=126$种,我$dfs$状态的时候省去了强制的$1$

#include 
#include
#include
#include
#include
using namespace std;typedef long long ll;const int N=128,MOD=30031;inline int read(){ char c=getchar();int x=0,f=1; while(c<'0'||c>'9'){
if(c=='-')f=-1;c=getchar();} while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();} return x*f;}int n,k,p;struct Matrix{ int a[N][N]; int* operator [](int x){
return a[x];} Matrix(){memset(a,0,sizeof(a));}}g;int st[N],m;inline void mod(int &x){
if(x>=MOD) x-=MOD;}Matrix operator *(Matrix a,Matrix b){ Matrix re;int n=m; for(int k=0;k
>=1,a=a*a) if(b&1) re=re*a; return re;}void dfs(int d,int num,int s){ //printf("Dfs %d %d %d\n",d,num,s); if(num==0) {st[m++]=s;return;} for(int i=d;i
>1);//printf("build %d %d %d\n",st[i],st[j],s); if(s == (s&-s)) g[i][j]=1; }}int main(){ freopen("in","r",stdin); n=read();k=read();p=read(); dfs(0,k-1,0); //for(int i=0;i

 

转载地址:http://apesl.baihongyu.com/

你可能感兴趣的文章
系统知识点笔记
查看>>
Gradle 2.3 发布
查看>>
数据库内核月报 - 2015 / 10-MySQL · 特性分析 · MySQL权限存储与管理
查看>>
Swift教程_零基础学习Swift完整实例(五)_swift完整实例(构建数据层)
查看>>
[Angularjs]asp.net mvc+angularjs+web api单页应用
查看>>
仿Linux中的cp操作
查看>>
【ANDROID游戏开发十五】关于ANDROID 游戏开发中 ONTOUCHEVENT() 触屏事件的性能优化笔记!...
查看>>
移动端web开发 chapter 1 – introduction
查看>>
获取时间的方法及常用时间类
查看>>
Git忽略文件
查看>>
如何删除或重置spfile中的参数
查看>>
Spring Boot 之 HelloWorld详解
查看>>
【RAC】如何修改vip 或者vip 对应的hostname
查看>>
Sql Server之旅——第三站 解惑那些背了多年聚集索引的人
查看>>
【LINUX】磁盘格式化 创建文件系统
查看>>
expect使用详解
查看>>
IOS(CGGeometry)几何类方法总结
查看>>
Quart2D setNeedsDisplay
查看>>
Android TextView点击效果
查看>>
GIX4中懒加载
查看>>