UPD 2021.4.9:修了个 typo,为啥写题解老出现 typo 啊(

Codeforces 题目传送门 & 洛谷题目传送门

这是一道 *2900 的 D1C,不过还是被我想出来了

u1s1 大概是这题用到的几个套路我都见过罢

首先注意到 \(k\) 很小,故考虑状压 \(dp\),\(dp_{i,s}\) 表示当前所有 pollywog 都在编号 \([i-k+1,i]\) 范围内的石头上,并且有且仅有编号 \(i-x+1,x\in s\) 的石头上有 pollywog。

转移还是比较显然的,如果 \(k\in s\),那么我们必须强制让这个当前位于 \(i-k+1\) 位置的 pollywog 跳 \(k\) 步,否则我们可以枚举一个青蛙并让它跳到编号为 \(i+1\) 的石头上,或者干脆 \(i+1\) 位置上不放 pollywog,也就是说:

  • \(dp_{i+1,s'}\leftarrow dp_{i,s}+c_k+a_{i+1},s'=\{x+1|x\in s\land x\ne k\}\cup\{1\}(k\in s)\)
  • \(dp_{i+1,s'}\leftarrow dp_{i,s}+c_d+a_{i+1},s'=\{x+1|x\in s\land x\ne d\}\cup\{1\}(k\notin s,d\in s)\)
  • \(dp_{i+1,s'}\leftarrow dp_{i,s}+c_k,s'=\{x+1|x\in s\}(k\notin s)\)

其中 \(c_i\) 为跳 \(i\) 格所需消耗的体力,\(a_i\) 为 \(i\) 所在的特殊格所额外消耗的体力(如果 \(i\) 不是特殊格则 \(a_i=0\))。

初始 \(dp_{x,\{1,2,\dots,x\}}=0\),答案为 \(dp_{n,\{1,2,\dots,x\}}\)。

考虑优化,注意到这个 \(n\) 很大但是这个转移呈规律性。故考虑矩阵优化 \(dp\),我们把转移方程用矩阵的形式表示出来,即我们总能找到一个矩阵 \(A\) 使得 \(A\times\begin{bmatrix}dp_{i,0}\\dp_{i,1}\\\dots\\dp_{i,2^k-1}\end{bmatrix}=\begin{bmatrix}dp_{i+1,0}\\dp_{i+1,1}\\\dots\\dp_{i+1,2^k-1}\end{bmatrix}\)(其中两个大小分别为 \(n\times m,m\times k\) 的矩阵 \(A,B\) 乘法得到的矩阵 \(C\) 为 \(n\times k\) 的矩阵,且 \(C_{i,j}=\min\limits_{l=1}^mA_{i,l}+B_{l,j}\))。那么如果没有什么特殊格子的限制的话,直接一遍矩阵快速幂就行了。

接下来考虑有特殊格子的情况,我们按照 CF576D 的套路将所有特殊格子按坐标排个序,显然一个特殊格子 \((x,y)\) 对 \(dp\) 值产生的影响就是令 \(\forall 1\in S,dp_{x,S}\leftarrow dp_{x,S}+y\)。故可以直接矩阵快速幂求出 \(dp_x\),然后就直接在 \(dp_x\) 上修改贡献即可。

这个算法的复杂度 \(\omega^3p\log n\) 的,其中 \(\omega=2^k\),无法通过。

考虑优化,注意到这个转移矩阵 \(A\) 是不会发生变化的,故考虑借鉴 P6772 的套路,而我们矩阵快速幂求出 \(dp_x\) 实质上是矩阵乘向量,单次乘法复杂度为 \(\omega^2\),故考虑预处理出 \(A^{2^k}\),这样可实现 \(\omega^3\log n\) 预处理,\(\omega^2p\log n\) 矩阵快速幂。

可是这样还是会炸啊……

这里还有第三个套路,就是对于合法的 \(dp_{i,S}\) 一定有 \(|S|=x\),故合法的状态最多 \(\binom{8}{4}=70\) 种,于是可以把所有合法的状态压缩成一个 \([1,70]\) 内的整数,这样矩阵大小就降到了 \(70\) 了。

时间复杂度 \(\omega^3\log n+\omega^2p\log n+\log p\),目前最优解 rk1

#include <bits/stdc++.h>
using namespace std;
#define fi first
#define se second
#define fill0(a) memset(a,0,sizeof(a))
#define fill1(a) memset(a,-1,sizeof(a))
#define fillbig(a) memset(a,63,sizeof(a))
#define pb push_back
#define ppb pop_back
#define mp make_pair
template<typename T1,typename T2> void chkmin(T1 &x,T2 y){if(x>y) x=y;}
template<typename T1,typename T2> void chkmax(T1 &x,T2 y){if(x<y) x=y;}
typedef pair<int,int> pii;
typedef long long ll;
typedef unsigned int u32;
typedef unsigned long long u64;
namespace fastio{
#define FILE_SIZE 1<<23
char rbuf[FILE_SIZE],*p1=rbuf,*p2=rbuf,wbuf[FILE_SIZE],*p3=wbuf;
inline char getc(){return p1==p2&&(p2=(p1=rbuf)+fread(rbuf,1,FILE_SIZE,stdin),p1==p2)?-1:*p1++;}
inline void putc(char x){(*p3++=x);}
template<typename T> void read(T &x){
x=0;char c=getchar();T neg=0;
while(!isdigit(c)) neg|=!(c^'-'),c=getchar();
while(isdigit(c)) x=(x<<3)+(x<<1)+(c^48),c=getchar();
if(neg) x=(~x)+1;
}
template<typename T> void recursive_print(T x){if(!x) return;recursive_print(x/10);putc(x%10^48);}
template<typename T> void print(T x){if(!x) putc('0');if(x<0) putc('-'),x=~x+1;recursive_print(x);}
void print_final(){fwrite(wbuf,1,p3-wbuf,stdout);}
}
const int MAXK=8;
const int MAXP=25;
const int MAX_SIZ=70;
const int LOG_N=28;
const ll INF=0x3f3f3f3f3f3f3f3fll;
int x,k,n,p,c[MAXK+2];pii t[MAXP+2];
int st[MAX_SIZ+5],st_n=0,id[1<<MAXK];
struct mat{
int n,m;ll a[MAX_SIZ+5][MAX_SIZ+5];
mat(){}
mat(int _n,int _m){
n=_n;m=_m;
for(int i=1;i<=n;i++) for(int j=1;j<=m;j++)
a[i][j]=INF;
}
mat operator *(const mat &rhs){
assert(m==rhs.n);mat res(n,rhs.m);
for(int i=1;i<=n;i++) for(int j=1;j<=rhs.m;j++)
for(int l=1;l<=m;l++) chkmin(res.a[i][j],a[i][l]+rhs.a[l][j]);
return res;
}
};
mat pw[LOG_N+2];
int main(){
scanf("%d%d%d%d",&x,&k,&n,&p);
for(int i=1;i<=k;i++) scanf("%d",&c[i]);
for(int i=1;i<=p;i++) scanf("%d%d",&t[i].fi,&t[i].se);
sort(t+1,t+p+1);
for(int i=0;i<(1<<k);i++) if(__builtin_popcount(i)==x){
st[++st_n]=i;id[i]=st_n;//printf("%d\n",i);
} mat trs(st_n,st_n);
for(int i=1;i<=st_n;i++){
if(st[i]>>(k-1)&1){
trs.a[id[((st[i]^(1<<(k-1)))<<1)|1]][i]=c[k];
} else {
for(int j=0;j<k;j++) if(st[i]>>j&1)
trs.a[id[((st[i]^(1<<j))<<1)|1]][i]=c[j+1];
trs.a[id[st[i]<<1]][i]=0;
}
}
// for(int i=1;i<=st_n;i++) for(int j=1;j<=st_n;j++)
// printf("%lld%c",trs.a[i][j],(j==st_n)?'\n':' ');
pw[0]=trs;
for(int i=1;i<=LOG_N;i++) pw[i]=pw[i-1]*pw[i-1];
int pre=x,init_msk=0;mat cur(st_n,1);
for(int i=0;i<x;i++) init_msk|=1<<i;
cur.a[id[init_msk]][1]=0;
for(int i=1;i<=p;i++){
int dif=t[i].fi-pre;
for(int j=LOG_N;~j;j--) if(dif>>j&1) cur=pw[j]*cur;
for(int j=1;j<=st_n;j++) if(st[j]&1) cur.a[j][1]+=t[i].se;
pre=t[i].fi;
}
int dif=n-pre;
for(int j=LOG_N;~j;j--) if(dif>>j&1) cur=pw[j]*cur;
printf("%lld\n",cur.a[id[init_msk]][1]);
// for(int i=1;i<=st_n;i++) printf("%d %lld\n",st[i],cur.a[i][1]);
return 0;
}

Codeforces 917C - Pollywog(状压 dp+矩阵优化)的更多相关文章

  1. BZOJ4000 [TJOI2015]棋盘 【状压dp + 矩阵优化】

    题目链接 BZOJ4000 题解 注意题目中的编号均从\(0\)开始= = \(m\)特别小,考虑状压 设\(f[i][s]\)为第\(i\)行为\(s\)的方案数 每个棋子能攻击的只有本行,上一行, ...

  2. HDU 5434 Peace small elephant 状压dp+矩阵快速幂

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5434 Peace small elephant  Accepts: 38  Submissions: ...

  3. 【BZOJ】2004: [Hnoi2010]Bus 公交线路 状压DP+矩阵快速幂

    [题意]n个点等距排列在长度为n-1的直线上,初始点1~k都有一辆公车,每辆公车都需要一些停靠点,每个点至多只能被一辆公车停靠,且每辆公车相邻两个停靠点的距离至多为p,所有公车最后会停在n-k+1~n ...

  4. 【bzoj2004】[Hnoi2010]Bus 公交线路 状压dp+矩阵乘法

    题目描述 小Z所在的城市有N个公交车站,排列在一条长(N-1)km的直线上,从左到右依次编号为1到N,相邻公交车站间的距离均为1km. 作为公交车线路的规划者,小Z调查了市民的需求,决定按下述规则设计 ...

  5. 【bzoj1097】[POI2007]旅游景点atr 状压dp+堆优化Dijkstra

    题目描述 FGD想从成都去上海旅游.在旅途中他希望经过一些城市并在那里欣赏风景,品尝风味小吃或者做其他的有趣的事情.经过这些城市的顺序不是完全随意的,比如说FGD不希望在刚吃过一顿大餐之后立刻去下一个 ...

  6. 【XSY2524】唯一神 状压DP 矩阵快速幂 FFT

    题目大意 给你一个网格,每个格子有概率是\(1\)或是\(0\).告诉你每个点是\(0\)的概率,求\(1\)的连通块个数\(\bmod d=0\)的概率. 最开始所有格子的概率相等.有\(q\)次修 ...

  7. 2018.09.28 hdu5434 Peace small elephant(状压dp+矩阵快速幂)

    传送门 看到n的范围的时候吓了一跳,然后发现可以矩阵快速幂优化. 我们用类似于状压dp的方法构造(1(1(1<<m)∗(1m)*(1m)∗(1<<m)m)m)大小的矩阵. 然后 ...

  8. [Bzoj2004][Hnoi2010]Bus 公交线路(状压dp&&矩阵加速)

    题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=2004 看了很多大佬的博客才理解了这道题,菜到安详QAQ 在不考虑优化的情况下,先推$dp ...

  9. BZOJ 4000: [TJOI2015]棋盘( 状压dp + 矩阵快速幂 )

    状压dp, 然后转移都是一样的, 矩阵乘法+快速幂就行啦. O(logN*2^(3m)) ------------------------------------------------------- ...

随机推荐

  1. 类图示例-订单系统 / Class Diagram - Order System

    类图示例-订单系统 / Class Diagram - Order System 什么是类图? 类图通过显示它的类和它们之间的关系来概述系统.类图是静态的 - 它们显示交互的内容,但不显示交互时会发生 ...

  2. Scrum Meeting 1补充会议

    日期:2021年04月24日 会议主要内容概述: 本次会议于11:30举行,对项目架构做出了重要调整,并根据该调整修改了第1次例会报告中后两日计划完成的工作部分. 一.架构调整 会上讨论了用户模块相关 ...

  3. 【技术博客】Flutter—使用网络请求的页面搭建流程、State生命周期、一些组件的应用

    Flutter-使用网络请求的页面搭建流程.State生命周期.一些组件的应用 使用网络请求的页面搭建流程 ​ 在开发APP时,我们常常会遇到如下场景:进入一个页面后,要先进行网络调用,然后使用调用返 ...

  4. 最详细的windows10系统封装教程

    目录 自定义封装(定制)windows10教程 关于本教程及用到的工具的声明 第一阶段: 封装前的各种环境准备 安装vmware 创建虚拟机 对虚拟机进行分区 配置好BIOS 为虚拟机安装window ...

  5. cURL 命令获取本机外网 IP

    1.1 查询本机外网 IP # curl dhcp.cn 134.175.159.160 1.2 输出格式为 JSON # curl dhcp.cn/?json { "IP": & ...

  6. 理解前端blob和ArrayBuffer,前端接受文件损坏的问题

    1 downloadTemplate().then(res =>{ 2 3 const data = res.data 4 const url = window.URL.createObject ...

  7. 从0到1使用Kubernetes系列(六):数据持久化实战

    本文是从 0 到 1 使用 Kubernetes 系列第六篇,上一篇<从 0 到 1 使用 Kubernetes 系列(五):Kubernetes Scheduling>介绍了 Kuber ...

  8. CVAT 用户指南

    用户指南 计算机视觉标注工具(CVAT)是基于 Web 为计算机视觉算法标注视频和图像的在线工具. 它的灵感来自Vatic免费的.在线的.交互式的视频注释工具. CVAT有许多强大的功能: 在关键帧之 ...

  9. Mac卸载go

    1.删除go目录 一般目录是 /usr/local/go sudo rm -rf /usr/local/go 2.清除环境变量配置 3. mac安装go后自动创建的问题也需要删除 sudo rm -r ...

  10. Spring Cache 带你飞(二)

    接着上一篇讲了 Spring Cache 如何被 Spring Aop 代理加载对应的代码,以及何如注入相关界面逻辑. Spring Cache 带你飞(一) 本篇我们围绕两个要点展开: 一个数据是如 ...