把博客园图标替换成自己的图标
把博客园图标替换成自己的图标end

题解 P3204 [HNOI2010] 公交线路

传送门

题意

显然。

分析

我们首先需要观察的就是我们的数据范围:N109P10K8。非常优秀的一个数据范围,我们马上可以筛选我们的算法,主体肯定有一个类倍增的算法加速转移,而转移有极大可能是通过状压来解决。

首先可以想到这样一个状态:fi,j 表示当前来到第 i 个车站,当前仍然停留有车的车站(显然使用状压,因为我们的 P 很小,我们可以用类似滚动数组的方式处理我们的状态)。

接下来解决一下转移。

由于我们题面的一个性质:1K 号站作为始发站,NK+1N 号台作为终点站。因此我们的过程中,车辆总数是始终为 k 的,这是一个小小的优化,也是转移的关键。

分为两种转移:

  1. 假如说边界上有车,那么这辆车必须,并且只能是这两者转移到 i
  2. 假如说没有,那么我们可以从前边任意一辆车开过来。

可以得到这样的代码:

for(int i=m; i<n; ++i) {
for(int j=0; j<=up; ++j) {
if(cnt[j]!=m) continue;//m即k
if(j&(1<<P-1)) f[i+1][(j<<1|1)&up]=(f[i+1][(j<<1|1)&up]+f[i][j])%MOD;
else {
for(int k=0; k<P-1; ++k) {
if((1<<k)&j) {
int st=j^(1<<k);
f[i+1][st<<1|1]=(f[i+1][st<<1|1]+f[i][j])%MOD;
}
}
}
}
}

我们后面的代码万变不离其宗,所以这一段代码一定要理解。

此时我们发现,可以拿到 40pts,时间复杂度:O(n×K×wP),(w=2),在空间与与时间上都受到限制。

紧接着,尝试优化我们的转移,首先就是最直白的,使用矩阵快速幂优化。

此处的代码大同小异,只是将原来的转移方式转化成矩阵上的节点 +1 即可。由于数据上的特殊,我们的优化并没有效果,反而只能拿到 10pts,时间复杂度:O(logn×w3×P)

接下来我们就需要思考优化我们的转移。

首先上面提及的那个特征:过程中,车辆总数是始终为 k 的,所以,我们的有用的节点实际只有 CPK 个,即最大只有 C105=252 个,可以使用一个 map 来进行离散化,现在我们就可以拿到 80 的高分。

继续考虑优化我们的有用个数,又可以观察到,我们的状态实际上第 0 位绝对是 1,又可以优化掉一位,拿下 100pts

int up=(1<<P)-1,cnt_m=0;
for(int i=1; i<=up; ++i) {
cnt[i]=cnt[i-lowbit(i)]+1;
if(cnt[i]==m&&(i&1)) ma[i>>1]=cnt_m++;
}
ans.n=1,ans.m=bas.n=bas.m=cnt_m;
ans.a[0][ma[((1<<m)-1)>>1]]=1;
for(int j=0; j<=up; ++j) {
if(cnt[j]!=m||(j&1)==0) continue;
if(j&(1<<P-1)) {
add(bas,ma[j>>1],ma[((j<<1|1)&up)>>1]);
} else {
for(int k=0; k<P-1; ++k) {
if((1<<k)&j) {
int st=j^(1<<k);
add(bas,ma[j>>1],ma[(st<<1|1)>>1]);
}
}
}
}
posted @   djh0314  阅读(20)  评论(0编辑  收藏  举报  
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 【杂谈】分布式事务——高大上的无用知识?
浏览器标题切换
浏览器标题切换end
点击右上角即可分享
微信分享提示