【2018集训队互测】【XSY3372】取石子
题目来源:2018集训队互测 Round17 T2
题意:
题解:
显然我是不可能想出来的……但是觉得这题题解太神了就来搬(chao)一下……Orzpyz!
显然不会无解……
为了方便计算石子个数,在最后面加一堆$a_i=c_i=\infty$的石子,确保每次取石子都可以取满$k$个;
先考虑$a_i=0$的情况:
设$f_{i,j}$表示只考虑第0到$i$堆石子,通关前$j$轮的最少操作次数;
设$g_{i,j}$表示只考虑第0到$i$堆石子,前$j$轮结束后再取若干次石子,每次取$k$个,使得第$i$堆前面的所有石堆都被取尽的最少操作次数;
分别记$sa,sb$为$a,b$的前缀和;
从小到大枚举$i,j$,每次考虑加入石堆$i$的影响,分两种情况转移:
若存在一种方案使得不取第$i$堆石子即可通关前$j$轮,此时需满足$j\times b_i\leq c_i$且$f_{i-1,j}\neq\infty$;
则转移为:
$f_{i,j}\leftarrow f_{i-1,j}$
$g_{i,j}\leftarrow \lceil\frac{j\times sb_{i-1}}{k}\rceil$
第二种转移需要满足石子总数够取,即$\lceil\frac{j\times sb_{i-1}}{k}\rceil\times k\leq j\times sb_i$;
否则枚举最后一次取$i$的轮数$r$,此时最优策略一定是分成三部分:
1.在前$r$轮取完$[0,i)$中的石子,这部分答案显然为$g_{i,r}$
2.这轮在$i$中取若干次石子,此时$i$中剩余石子数为$m=r\times sb_i-k\times g_{i,r}$,为了使它在$j$轮后不超过限制,还需要取$x=\lceil\frac{max(0,m+(j-r)\times b_i-c_i)}{k}\rceil$次;若$x\times k>m$,即石子不够取,则无解;
3.在剩余的$j-r$轮中取石子,这部分跟第一种情况类似,可以得到$f$的操作数为$f_{i-1,j-r}$,$g$的操作数为$g_{i,j}$;
因此转移就是:
$f_{i,j}\leftarrow g_{i,r}+f_{i-1,j-r}+x$
$g_{i,j}\leftarrow g_{i,r}+\lceil\frac{(j-r)\times sb_{i-1}}{k}\rceil+x$
时间复杂度$O(nt^2)$;
考虑$a_i\neq 0$的情况,可以发现此时对dp的影响只有第二种情况的第三步中,所有石堆的个数都为0;那么直接在$f,g$后面加一维0/1位表示每堆石子初始时是否有值,在第三步转移中用$f_{i-1,j-r,0}$转移,每次计算剩余石子时注意初始的$a_i$即可;
代码看(chao)了天下第一wxh的代码
代码:
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<queue>
#define inf 100000000000000000
#define eps 1e-9
using namespace std;
typedef long long ll;
typedef double db;
int n,t,k;
ll tmp,tt,m,a[],b[],c[],sa[],sb[],f[][][],g[][][];
int main(){
scanf("%d%d%d",&n,&t,&k);
for(int i=;i<=n;i++){
scanf("%lld%lld%lld",&a[i],&b[i],&c[i]);
sa[i]=sa[i-]+a[i];
sb[i]=sb[i-]+b[i];
}
n++;
a[n]=c[n]=sa[n]=inf;
sb[n]=sb[n-];
for(int i=;i<=n;i++){
for(int j=;j<=t;j++){
for(int t=;t<=;t++){
f[i][j][t]=g[i][j][t]=inf;
//transform 1
if(j*b[i]+t*a[i]<=c[i]&&f[i-][j][t]!=inf){
f[i][j][t]=f[i-][j][t];
tmp=(j*sb[i-]+t*sa[i-]+k-)/k;
if(tmp*k<=j*sb[i]+t*sa[i]){
g[i][j][t]=tmp;
}
}
//transform 2
for(int r=;r<j;r++){
if(g[i][r][t]!=inf){
m=r*sb[i]+t*sa[i]-k*g[i][r][t];
tmp=(max(0ll,m+(j-r)*b[i]-c[i])+k-)/k;
if(tmp*k<=m&&f[i-][j-r][]!=inf){
f[i][j][t]=min(f[i][j][t],f[i-][j-r][]+g[i][r][t]+tmp);
tt=((j-r)*sb[i-]+k-)/k;
if(tt*k<=(j-r)*sb[i]+m-tmp*k){
g[i][j][t]=min(g[i][j][t],g[i][r][t]+tmp+tt);
}
}
}
}
}
}
}
printf("%lld",f[n][t][]);
return ;
}
【2018集训队互测】【XSY3372】取石子的更多相关文章
- 【loj2461】【2018集训队互测Day 1】完美的队列
#2461. 「2018 集训队互测 Day 1」完美的队列 传送门: https://loj.ac/problem/2461 题解: 直接做可能一次操作加入队列同时会弹出很多数字,无法维护:一个操作 ...
- [JZOJ6088] [BZOJ5376] [loj #2463]【2018集训队互测Day 1】完美的旅行【线性递推】【多项式】【FWT】
Description Solution 我们考虑将问题一步步拆解 第一步求出\(F_{S,i}\)表示一次旅行按位与的值为S,走了i步的方案数. 第二步答案是\(F_{S,i}\)的二维重复卷积,记 ...
- 【LOJ2461】「2018 集训队互测 Day 1」完美的队列(分块+双指针)
点此看题面 大致题意: 让你维护\(n\)个有限定长度的队列,每次区间往队列里加数,求每次加完后的队列里剩余元素种类数. 核心思路 这道题可以用分块+双指针去搞. 考虑求出每个操作插入的元素在队列中被 ...
- @loj - 2461@ 「2018 集训队互测 Day 1」完美的队列
目录 @description@ @solution@ @part - 0@ @part - 1@ @accepted code@ @details@ @description@ 小 D 有 n 个 ...
- LOJ2476. 「2018 集训队互测 Day 3」蒜头的奖杯 & LOJ2565. 「SDOI2018」旧试题(莫比乌斯反演)
题目链接 LOJ2476:https://loj.ac/problem/2476 LOJ2565:https://loj.ac/problem/2565 题解 参考照搬了 wxh 的博客. 为了方便, ...
- 洛谷 P4463 - [集训队互测 2012] calc(多项式)
题面传送门 & 加强版题面传送门 竟然能独立做出 jxd 互测的题(及其加强版),震撼震撼(((故写题解以祭之 首先由于 \(a_1,a_2,\cdots,a_n\) 互不相同,故可以考虑求出 ...
- 【纪中集训2019.3.27】【集训队互测2018】小A的旅行(白)
题目 描述 \(0-n-1\)的图,满足\(n\)是\(2\)的整数次幂, $ i \to j $ 有 $ A_{i,j} $ 条路径: 一条路径的愉悦值定义为起点和终点编号的\(and\)值 ...
- EZ 2018 05 06 NOIP2018 慈溪中学集训队互测(五)
享受爆零的快感 老叶本来是让初三的打的,然后我SB的去凑热闹了 TM的T2写炸了(去你妹的优化),T1连-1的分都忘记判了,T3理所当然的不会 光荣革命啊! T1 思维图论题,CHJ dalao给出了 ...
- UOJ#191. 【集训队互测2016】Unknown 点分治 分治 整体二分 凸包 计算几何
原文链接https://www.cnblogs.com/zhouzhendong/p/UOJ191.html 题目传送门 - UOJ191 题意 自行移步集训队论文2016中罗哲正的论文. 题解 自行 ...
随机推荐
- Remote Desktop安卓软件实现手机远程控制电脑
这篇文章写的是利用Remote Desktop安卓软件实现手机远程控制电脑. 电脑上的操作: 鼠标右击计算机>属性>远程设置>计算机名 如下图:
- js面向对象 多种创建对象方法小结
转自js面向对象 多种创建对象方法小结 1.对象字面量 var clock={ hour:12, minute:10, second:10, showTime:function(){ alert(th ...
- UVA 10173
bitch bitch bitch... TLE,WA一大坨,我是在拿生命来JUDGE啊.. 不得不说,UVA上的数据根本不是随机的,而是有预谋的. for(int i=2;i<n;i++){ ...
- HDU 1242
简单题 #include <iostream> #include <cstdio> #include <queue> using namespace std; ; ...
- 怎样手动的干净的删除linux上的ORACLE数据库
近期在用VMWARE虚拟机做ORACLE的数据库实验.我们都知道在WINDOWS上,我能够到加入删除程序里去自己主动删除已经安装的全部的应用程序.可是在LINUX上没有这个服务能够进行自己主动的删除. ...
- Marching squares & Marching cubes
提要 Marching squares 主要是用于从一个地图(用二维数组表示)生成轮廓的算法.Marching cubes则相应的是在空间生成网格的方法.最常见的应用就是天气预报中气压图的生成.还经常 ...
- GitLab创建项目
创建自己的项目:通过地址进入 在文件夹下使用git bash进行 git init,然后ctrl+右键使用TortoiseGit>右键setting 然后再右键setting 拷贝代码时注意要h ...
- B1965 [Ahoi2005]SHUFFLE 洗牌 数论
这个题的规律很好找,就是奇数直接除二,偶数除二加n/2.把这个规律整理一下就是(x * 2) % (n + 1),然后就直接求逆元就行了.一直30分的原因是qpow函数传参的时候用的int,然而变量是 ...
- rehat7.X下postgresql 11编译安装
文档目录结构: 一.准备 操作系统版本:rehat7.6 Postgresql:11.2 软件安装目录:/pgsql11/basedir 数据文件存放目录:/pgsql11data/ 11.2的下载地 ...
- IP与以太网的包收发操作
你好,这是<网络是怎样连接的>的第3篇读书笔记,第二章<用电信号传输TCP/IP>后半部分:IP与以太网的包收发操作. 先看下经典的TCP/IP四层模型: 通常,下层模块支撑上 ...