Codeforces917C. Pollywog
$n \leq 1e8$个石头,$x \leq 8$个蝌蚪一开始在最左边$x$个石子,要跳到最右的$x$个,每次只能最左边的蝌蚪跳一次,一个石头不能站两个蝌蚪,跳可以跳$1到k,x \leq k \leq 8$步,跳$i$步的代价是$cost_i$,还有$q \leq 25$个神奇石头,跳上去代价会$+w_i$,$w_i$可能为负数。问完成跳跃的最小代价。
不知道跳蝌蚪是什么操作只听过跳蛤,大概是变相膜?
好的严肃。从小数字$x$和$k$入手。由于每次只有最左的蝌蚪会跳,所以这$x$个蝌蚪一定每时每刻都在某连续的$k$个石头上。记这$k$个石头最左的那个(不一定上面有蝌蚪)为$i$,那么$i$处右边$k$个石子上的蝌蚪状态可以用二进制表示,最多是$C_8^4=70$个状态,挺小。这样就可以做转移了,转移复杂度是$C_k^x*k$,再乘个$n$直接爆炸。不过我们来看这个转移,$dp(i,j)=dp(i-1,k)+cost_t$,想到啥了?走若干步的最短路!这是可以用矩乘优化的,于是在不考虑$q$时,可以做$log_2n*(C_k^x)^3$的$dp$。
然后来看$q$。一块神奇石头影响了$k$块地(di)的(de)转移,因此最多会有$q*k$块地受影响,挺小,矩乘到这些地段时停住,暴力转移。最终复杂度$log_2n*(C_k^x)^3+qk^2C_k^x$。
//#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
//#include<map>
#include<math.h>
//#include<time.h>
//#include<complex>
#include<algorithm>
using namespace std; int X,K,n,m,q;
#define LL long long
const LL inf=1e18;
struct Mat
{
LL a[][];
Mat() {for (int i=;i<=;i++) for (int j=;j<=;j++) a[i][j]=inf;}
Mat operator * (const Mat &b)
{
Mat ans;
for (int k=;k<=m;k++)
for (int i=;i<=m;i++)
for (int j=;j<=m;j++)
ans.a[i][j]=min(ans.a[i][j],a[i][k]+b.a[k][j]);
return ans;
}
}base,f; Mat pow(Mat a,int b)
{
Mat ans,tmp=a; for (int i=;i<=m;i++) ans.a[i][i]=;
while (b)
{
if (b&) ans=ans*tmp;
tmp=tmp*tmp; b>>=;
}
return ans;
} int state[],ls,who[];
struct Ran{int l,r;}qq[],ran[]; int len;
LL g[],h[];int cost[];
struct Block{int pos,w;}ww[];
bool cmpww(const Block &a,const Block &b) {return a.pos<b.pos;}
struct Hash
{
int first[],le; struct Edge{int to,v,next;}edge[];
Hash() {le=;}
void insert(int x,int y) {int h=x%; Edge &e=edge[le]; e.to=x; e.v=y; e.next=first[h]; first[h]=le++;}
int find(int x) {int h=x%; for (int i=first[h];i;i=edge[i].next) if (edge[i].to==x) return edge[i].v; return -2e9;}
}ha; int main()
{
scanf("%d%d%d%d",&X,&K,&n,&q);
for (int i=;i<=K;i++) scanf("%d",&cost[i]);
for (int i=;i<=q;i++) scanf("%d%d",&ww[i].pos,&ww[i].w); sort(ww+,ww++q,cmpww);
LL ans=; for (int &i=q;i;i--) if (ww[i].pos>=n-X+) ans+=ww[i].w; else break;
for (int i=;i<=q;i++) ha.insert(ww[i].pos,ww[i].w);
for (int i=;i<=q;i++) qq[i].l=max(ww[i].pos-K,),qq[i].r=ww[i].pos;
len=; for (int i=;i<=q;i++)
{
if (len && qq[i].l<=ran[len].r+) ran[len].r=qq[i].r;
else len++,ran[len].l=qq[i].l,ran[len].r=qq[i].r;
}
ls=; for (int i=;i<(<<K);i++)
{
int cnt=;
for (int j=;j<K;j++) if ((i>>j)&) cnt++;
if (cnt==X) ls++,state[i]=ls,who[ls]=i;
} m=ls;
for (int i=;i<=ls;i++)
{
int s=who[i]>>;
if ((who[i]&)==) base.a[i][state[s]]=;
else for (int j=;j<=K;j++) if (((s>>(j-))&)==) base.a[i][state[s|(<<(j-))]]=cost[j];
}
f.a[][]=; ran[].r=;
for (int i=;i<=len;i++)
{
f=f*pow(base,ran[i].l-ran[i-].r-);
for (int j=;j<=ls;j++) g[j]=f.a[][j];
for (int j=ran[i].l;j<=ran[i].r;j++)
{
for (int k=;k<=ls;k++) h[k]=inf;
for (int k=;k<=ls;k++)
{
int s=who[k]>>;
if ((who[k]&)==) h[state[s]]=min(h[state[s]],g[k]);
else for (int l=,tmp;l<=K;l++) if (((s>>(l-))&)==)
{
int ns=s|(<<(l-));
if ((tmp=ha.find(j+l-))!=-2e9) h[state[ns]]=min(h[state[ns]],g[k]+cost[l]+tmp);
else h[state[ns]]=min(h[state[ns]],g[k]+cost[l]);
}
}
for (int k=;k<=ls;k++) g[k]=h[k];
}
for (int j=;j<=ls;j++) f.a[][j]=g[j];
}
f=f*pow(base,n-X+-ran[len].r);
printf("%lld\n",ans+f.a[][]);
return ;
}
Codeforces917C. Pollywog的更多相关文章
- CF917C Pollywog —— 状压DP + 矩乘优化
C. Pollywog 题目描述 原题题目链接.题目大意为:有$x$只蝌蚪,在$n$个石头中的最左端的$x$个石头上,这$n$个石头是在同一直线上的.每一次只能最左边的一个蝌蚪进行跳跃,并且只能跳$1 ...
- Codeforces 917C - Pollywog(状压 dp+矩阵优化)
UPD 2021.4.9:修了个 typo,为啥写题解老出现 typo 啊( Codeforces 题目传送门 & 洛谷题目传送门 这是一道 *2900 的 D1C,不过还是被我想出来了 u1 ...
- Pollywog CodeForces - 917C (状压)
链接 大意: 一共n个格子, 初始$x$只蝌蚪在前$x$个格子, 每次最左侧的蝌蚪向前跳, 跳跃距离在范围[1,k], 并且每只蝌蚪跳跃都有一定花费, 有$q$个格子上有石头, 若有蝌蚪跳到某块石头上 ...
随机推荐
- 用户授权policy
定义策略类 php artisan make:policy PostPolicy app/Policies/PostPolicy.php public function update(User $us ...
- 【转载】Hierarchal Temporal Memory (HTM)
最近在看机器学习,看能否根据已有的历史来预测Hardware的故障发生概率.下文是一篇很有意思的文章,转自 http://numenta.org/htm.html. NuPIC是一个开源项目,用来实现 ...
- 46 Simple Python Exercises-Higher order functions and list comprehensions
26. Using the higher order function reduce(), write a function max_in_list() that takes a list of nu ...
- asp.net mvc 5 微信接入VB版 - 接入认证
微信接入官方文档是php的,网上被抄好几遍的代码是c#的,就是没vb的.今天我把这个坑填了,做vb版的接入认证. 首先是照着开发文档把微信接入的模型写好.在Models文件夹新建一个Model Pub ...
- 推荐一个高大上的网易云音乐命令行播放工具:musicbox
网易云音乐上有很多适合程序猿的歌单,但是今天文章介绍的不是这些适合程序员工作时听的歌,而是一个用Python开发的开源播放器,专门适用于网易云音乐的播放.这个播放器的名称为MusicBox, 特色是用 ...
- 使用Recast.AI创建具有人工智能的聊天机器人
很多SAP顾问朋友们对于人工智能/机器学习这个话题非常感兴趣,也在不断思考如何将这种新技术和SAP传统产品相结合.Jerry之前的微信公众号文章C4C和微信集成系列教程曾经介绍了Partner如何利用 ...
- app自动化配置信息
caps={ "platformName":"Android",#平台名称 "platformVersion":"6. ...
- PHP06 流程控制
学习要点 选择结构 循环结构 学习目标 掌握PHP的选择结构 掌握PHP的循环结构 流程控制概述 程序 程序:一系列计算机指令的集合. 编程语言:开发程序的工具. 程序执行结构 计算机程序有三种基本执 ...
- Proguard配置文件内容
-injars elec-bendao-1.2.jar-outjars elec-bendao-1.2-end.jar -libraryjars lib\charsets.jar-libraryjar ...
- node的影响及前后端之争
作者:知乎用户链接:https://www.zhihu.com/question/59578433/answer/326694511来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请 ...