BZOJ 2004 [Hnoi2010]Bus 公交线路 - 状压DP+矩阵快速幂
2017-10-25 08:05
525 查看
4000
看数据范围,算法一目了然,然而。。。并不会啊
由于p位的限制,所有车一定在p位的限制内转移,于是考虑这样的状压:
设一个p位的二进制码,以第一辆车作为视角向后p位,要求p位之内有k辆车。而且由于是以第一辆车作为视角,于是第一位一定是1。设立dp数组dp i j,表示第一辆车在坐标i处,其后的状态为j,dp转移方程为:dp[i][S]=∑dp[i−1][S′]⋅r[S′][S],其中要求S可以转移到S’的状态,r为转移数组。后边的式子可以用矩阵优化,由于所有车谁先走是无所谓的,状态数即答案。
解释一下能否进行转移的判断:由于S’的整体坐标比S后1位,于是给S整体左移一位,末尾由于无车一定补0,。由于必然是S的k位中的一位到了S’第一位的位置,于是后p位S<<1一定比S’多一个0,即此位的1转移到了开头。
一般这种可以列出转移矩阵的,一般用矩阵加速幂
看数据范围,算法一目了然,然而。。。并不会啊
由于p位的限制,所有车一定在p位的限制内转移,于是考虑这样的状压:
设一个p位的二进制码,以第一辆车作为视角向后p位,要求p位之内有k辆车。而且由于是以第一辆车作为视角,于是第一位一定是1。设立dp数组dp i j,表示第一辆车在坐标i处,其后的状态为j,dp转移方程为:dp[i][S]=∑dp[i−1][S′]⋅r[S′][S],其中要求S可以转移到S’的状态,r为转移数组。后边的式子可以用矩阵优化,由于所有车谁先走是无所谓的,状态数即答案。
解释一下能否进行转移的判断:由于S’的整体坐标比S后1位,于是给S整体左移一位,末尾由于无车一定补0,。由于必然是S的k位中的一位到了S’第一位的位置,于是后p位S<<1一定比S’多一个0,即此位的1转移到了开头。
一般这种可以列出转移矩阵的,一般用矩阵加速幂
#include<iostream> #include<cstdlib> #include<cstring> #include<cstdio> #include<algorithm> using namespace std; const int maxn=210; const int mod=30031; int n,k,m,p,cnt,Begin; int shaker[maxn]; struct Matrix { int m[maxn][maxn]; }A,B; int getnum(int x) { int res=0; while(x) { x-=x&-x; res++; } return res; } bool Transfer(int From,int To) { From=(From<<1)-(1<<p);//from左移一位且末位用0补齐 return getnum(From^To)==1;//To比From有一位多1,代表此位原来的车从此地出发到了开头 } Matrix mul(Matrix x,Matrix y) { Matrix tmp; memset(tmp.m,0,sizeof tmp.m); for(int i=1;i<=cnt;i++) for(int j=1;j<=cnt;j++) for(int k=1;k<=cnt;k++) tmp.m[i][j]=(tmp.m[i][j]+x.m[i][k]*y.m[k][j])%mod; return tmp; } Matrix pow(Matrix x,int y) { y--; Matrix basic=x; while(y) { if(y&1)x=mul(x,basic); basic=mul(basic,basic); y>>=1; } return x; } int main() { scanf("%d%d%d",&n,&k,&p); for(int i=(1<<(p-1));i<=(1<<p)-1;i++)//筛出合法情况 { if(getnum(i)==k)//p格中恰有k个1 { shaker[++cnt]=i; if(i==(1<<p)-(1<<(p-k)))Begin=cnt;//寻找初始/终止状态 } } for(int i=1;i<=cnt;i++)//构造转移矩阵 for(int j=1;j<=cnt;j++) B.m[i][j]=Transfer(shaker[i],shaker[j]);//查询是否可以转移 A.m[1][Begin]=1;//初值 B=pow(B,n-k);//终止状态第一位坐标-初始状态第一位坐标=n-k A=mul(A,B); printf("%d",A.m[1][Begin]); return 0; }
相关文章推荐
- BZOJ2004: [Hnoi2010]Bus 公交线路
- 【HNOI2010】【BZOJ2004】Bus 公交线路
- [BZOJ2004][Hnoi2010]Bus 公交线路(状压DP+矩阵乘法)
- BZOJ 2004: [Hnoi2010]Bus 公交线路 [DP 状压 矩阵乘法]
- [BZOJ2004][Hnoi2010]Bus 公交线路
- [BZOJ 2004] [Hnoi2010] Bus 公交线路 【状压DP + 矩阵乘法】
- BZOJ2004 HNOI2010公交线路(状压dp+矩阵快速幂)
- bzoj 2004: [Hnoi2010]Bus 公交线路
- 【BZOJ 2004】: [Hnoi2010]Bus 公交线路
- [BZOJ]2004: [Hnoi2010]Bus 公交线路 状态压缩DP+矩阵乘法
- 【BZOJ】2004: [Hnoi2010]Bus 公交线路 状压DP+矩阵快速幂
- 【bzoj2004】[Hnoi2010]Bus 公交线路 状压dp+矩阵乘法
- bzoj 2004: [Hnoi2010]Bus 公交线路
- bzoj 2004[Hnoi2010]Bus 公交线路
- BZOJ 2004: [Hnoi2010]Bus 公交线路
- [BZOJ 2004][HNOI 2010]Bus 公交线路(矩阵快速幂加速DP)
- bzoj 2004: [Hnoi2010]Bus 公交线路 状压dp+矩阵乘法
- 【bzoj2004】[Hnoi2010]Bus 公交线路
- 【bzoj2004】[Hnoi2010]Bus 公交线路
- 【BZOJ2004】[Hnoi2010]Bus 公交线路 状压+矩阵乘法