标签:示例 opera ons 城市 数据规模 print -- blog fine
[BZOJ2004][Hnoi2010]Bus 公交线路
试题描述
输入
输出
输入示例
10 2 4
输出示例
81
数据规模及约定
P<=10 , K <=8
题解
状压 dp + 矩阵乘法。
话说最近还想自己出一道这两种算法结合在一起的题呢。。。
这题目标状态只需要让 K 辆车分别在最后 K 个位置即可,顺序没有规定。所以这题设计状态时也不用考虑顺序。我们令 f(i, S) 表示前 i-1 个都已经经过了,第 i 到第 i + P - 1 个位置的状态为 S 的方案数,这里的“方案”可以理解成 K 个公交车所在位置的集合,也可以理解成覆盖过的位置的集合,这两个理解是等价的(原因在于我们转移时只考虑最靠左的公交车移到哪,与此同时 i 要加 1,即我们关注的位置区间向右错一格,所以一个公交车移开之后变成“没有公交车”状态的位置不会出现在状态中)。
由于 n 很大,而每次转移都是形如 f(i, S) -> f(i+1, tS),所以可以构造转移矩阵做矩阵快速幂。
注意最靠前那一位必须是 1,这样可以省掉一部分状态。
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cctype>
#include <algorithm>
using namespace std;
int read() {
int x = 0, f = 1; char c = getchar();
while(!isdigit(c)){ if(c == ‘-‘) f = -1; c = getchar(); }
while(isdigit(c)){ x = x * 10 + c - ‘0‘; c = getchar(); }
return x * f;
}
#define maxS 1024
#define maxs 260
#define MOD 30031
struct Matrix {
int n, m, A[maxs][maxs];
Matrix() { memset(A, 0, sizeof(A)); }
Matrix(int _, int __): n(_), m(__) { memset(A, 0, sizeof(A)); }
Matrix operator * (const Matrix& t) const {
Matrix ans(n, t.m);
for(int i = 1; i <= ans.n; i++)
for(int j = 1; j <= ans.m; j++)
for(int k = 1; k <= m; k++)
ans.A[i][j] = (ans.A[i][j] + A[i][k] * t.A[k][j]) % MOD;
return ans;
}
Matrix operator *= (const Matrix& t) {
*this = *this * t;
return *this;
}
} base, tr;
Matrix Pow(Matrix a, int b) {
Matrix ans = a, t = a; b--;
while(b) {
if(b & 1) ans *= t;
t *= t; b >>= 1;
}
return ans;
}
int id[maxS], cnts;
int main() {
int n = read(), K = read(), P = read();
int all = (1 << P) - 1;
for(int S = 0; S <= all; S++) {
int cnt = 0;
for(int j = 0; j < P; j++) cnt += S >> j & 1;
if(cnt == K && (S & 1)) id[S] = ++cnts;
}
tr = Matrix(cnts, cnts);
for(int S = 0; S <= all; S++) if(id[S]) {
int tS = S >> 1;
for(int j = 0; j < P; j++) if(!(tS >> j & 1) && id[tS|(1<<j)]) tr.A[id[tS|(1<<j)]][id[S]]++;
}
base = Matrix(cnts, 1);
base.A[1][1] = 1;
base = Pow(tr, n - K) * base;
printf("%d\n", base.A[1][1]);
return 0;
}
标签:示例 opera ons 城市 数据规模 print -- blog fine
原文地址:http://www.cnblogs.com/xiao-ju-ruo-xjr/p/6938919.html