bzoj 2004 【hnoi2010】公交线路
来源:互联网 发布:ug8.5数控编程视频教程 编辑:程序博客网 时间:2024/04/30 21:56
时间限制:1秒 内存限制:64M
【问题描述】
小 Z 所在的城市有 N 个公交车站,排列在一条长为 N-1 公里的直线上,从左到右依次编号为 1 到 N,相邻公交车站间的距离均为 1 公里。
作为公交车线路的规划者,小 Z 调查了市民的需求,决定按以下规则设计线路:
1.设共有 K 辆公交车,则 1 到 K 号车站作为始发站, N-K+1 到 N 号车站作为终点站。
2.每个车站必须被一辆且仅一辆公交车经停(始发站和终点站也算被经停)。
3.公交车只能从编号较小的车站驶向编号较大的车站。
4.一辆公交车经停的相邻两个车站间的距离不得超过 P 公里。
注意“经停”是指经过并停车, 因经过不一定会停车,故经停与经过是两个不同的概念。
在最终确定线路之前,小 Z 想知道有多少种满足要求的方案。由于答案可能很大,你只需求出答案对 30031 取模的结果。
【输入格式】
只有一行,其中包含用空格隔开的三个正整数N, K,P, 分别表示公交车站数,公交车数, 一辆公交车经停的相邻两个车站间的最大距离。
【输出格式】
仅包含一个整数,表示满足要求的方案数对 30031 取模的结果。
【输入样例】
【样例1】
10 3 3
【样例2】
5 2 3
【样例3】
10 2 4
【输出样例】
【样例1】
1
【样例2】
3
【样例3】
81
【样例解释】
样例一满足要求的方案只有1种,即: (1,4,7,10), (2,5,8), (3,6,9)。
样例二满足要求的方案有3种,即: (1,3,5), (2,4); (1,3,4), (2,5)和(1,4), (2,3,5)。
【数据范围】
40%的数据满足N≤1000。
100%的数据满足1 < N < 10^9, 1 < P ≤1 0, K < N, 1 < K ≤ P
【来源】
bzoj 2004
一道极其坑的题,开始想了好久都没有思路。
先说一下我看到这道题的第一反应吧:
1.p<=10 一定是状态压缩用的。
2.n<=1*10^9 作为一道递推绝对要用矩阵优化。
然后我就卡死了,推了好久才得出的方程。
d[i][A]:前i个站最后p个站的n辆车最后停的位置为A(停了的2进制位就为1)的方案数。(最后一个站必须有车停)
转移的时候我们强制第一个先走,走一步(不然会重)。这样就可以得出哪些情况之间可以转移了。我们就可以矩阵优化了。
答案就是最后n个站都有车停的情况。
代码如下:
#include<cstdlib>#include<cstdio>#include<cstring>#include<iostream>using namespace std;const int maxn=150;const int mod=30031;struct mat{ int n,m,v[maxn][maxn]; mat() { memset(v,0,sizeof(v)); m=n=0; } friend mat operator * (mat a,mat b) { mat c; c.m=a.n;c.n=b.m; for(int i=1;i<=c.m;i++) for(int j=1;j<=b.m;j++) for(int k=1;k<=a.m;k++) c.v[i][j]=(c.v[i][j]+a.v[i][k]*b.v[k][j])%mod; return c; }}a,B;int g[maxn],top=0,n,m,p,b[maxn],ans;int work(int x){ int t=0; while(x) { t++; x-=(x&(-x)); } return t;}bool check(int i,int j){ int x=g[i],y=g[j]; x=x<<1; x-=b[p+1]; x=x^y; return x-(x&(-x))==0;}mat qkpow(mat a,int x){ mat t,c; c.m=c.n=a.m; for(int i=1;i<=c.m;i++) c.v[i][i]=1; t=a; while(x) { if (x&1) c=c*t; x=x>>1; t=t*t; } return c;}int main(){ //freopen("in.txt","r",stdin); //freopen("out.txt","w",stdout); scanf("%d%d%d",&n,&m,&p); b[1]=1;for(int i=2;i<=p+1;i++) b[i]=b[i-1]<<1; for(int i=b[p];i<=b[p+1]-1;i++) if(work(i)==m) { g[++top]=i; if(i==b[p+1]-b[p-m+1]) ans=top; } a.m=a.n=top; for(int i=1;i<=top;i++) for(int j=1;j<=top;j++) if(check(i,j)) a.v[j][i]=1; B.n=top,B.m=1; B.v[ans][1]=1; B=qkpow(a,n-m)*B; printf("%d\n",B.v[ans][1]); return 0;}
- bzoj 2004 【hnoi2010】公交线路
- BZOJ 2004: [Hnoi2010]Bus 公交线路
- bzoj 2004: [Hnoi2010]Bus 公交线路
- BZOJ 2004 [Hnoi2010]Bus 公交线路
- 2004: [Hnoi2010]Bus 公交线路
- [BZOJ]2004: [Hnoi2010]Bus 公交线路 状态压缩DP+矩阵乘法
- bzoj 2004: [Hnoi2010]Bus 公交线路 状压dp+矩阵乘法
- 【HNOI2010】【BZOJ2004】Bus 公交线路
- [BZOJ2004][Hnoi2010]Bus 公交线路
- 【bzoj2004】[Hnoi2010]Bus 公交线路
- BZOJ 1997: [Hnoi2010]Planar
- bzoj 1997: [Hnoi2010]Planar
- BZOJ 1997 [Hnoi2010]Planar
- BZOJ 2001 Hnoi2010 城市建设
- [BZOJ2004][HNOI2010]公交线路(状压DP+矩阵乘法)
- 【BZOJ 1996】 [Hnoi2010]chorus 合唱队
- bzoj 1996 [Hnoi2010]chorus 合唱队
- BZOJ 1996: [Hnoi2010]chorus 合唱队
- 数值积分
- 十分钟搞定pandas
- makefile制作和逐步推进过程
- 自定义View入门必看
- 3月25日 4C(华中赛区,郑轻)参赛感想
- bzoj 2004 【hnoi2010】公交线路
- CPP_Basic_Code_P2.1-PP2.7.7
- Eclipse下Java Resources报红叉问题
- log4cplus应用之日志文件输出(三)
- 第六届蓝桥杯加法变乘法
- 一、swift3.0简介
- IDEA 常用配置 和插件
- leetcode 477 Total Hamming Distance
- 第5节 分析system_call中断处理过程【Linux内核分析】