丘中有麻plant

改自这儿,by ZBQ。









还有隐藏的一页不放了。。

直接走下去的话,如果开始时间确定那么到每个点的时间确定,把time减去dis就可以去掉路程的影响了。

这样对于减去d后的t,如果想要摘一部分,那么应是取其中最大的t恰好摘它,其它t较小的会早熟然后等着。。(意会一下吧)

所以t大的会对t小的产生贡献,而要恰好摘t小的,那就摘不了t大的了。

所以对t排序并不会影响答案。从小到大依次分K段就行了。i对其中每个作物j的贡献是ti-tj。

注意t相等时虽然会同时摘,但是不能直接去重!因为如果不恰好摘它们,其它的会对它们所有产生贡献。。

所以考试的时候只有10分。。

某些剪枝之类的优化还是想好再加吧。没啥用又不会被卡T,不如不加。

#include <cstdio>
#include <cctype>
#include <cstring>
#include <algorithm>
//#define gc() getchar()
#define MAXIN 200000
#define gc() (SS==TT&&(TT=(SS=IN)+fread(IN,1,MAXIN,stdin),SS==TT)?EOF:*SS++)
typedef long long LL;
const int N=2e5+5; int n,K,q[N],num[N];//longlong
LL tm[N],sum[N],f[N],C;
char IN[MAXIN],*SS=IN,*TT=IN; inline int read()
{
int now=0;register char c=gc();
for(;!isdigit(c);c=gc());
for(;isdigit(c);now=now*10+c-'0',c=gc());
return now;
}
namespace Spec
{
int n,Now,q[N];//longlong
LL sum[N],f[2][N];
inline LL Y(int j,int k){
return f[Now][j]-f[Now][k]+sum[j]-sum[k];
}
inline LL X(int j,int k){
return j-k;
}
inline LL Calc(int fr,int to,int k){
return f[Now][fr]+(to-fr)*tm[to]-sum[to]+sum[fr];
}
void Main()
{
for(int i=1; i<=n; ++i) sum[i]=sum[i-1]+(LL)tm[i];
memset(f,0x7f,sizeof f);
f[0][0]=0, Now=0;
for(int j=1; j<=K; ++j, Now^=1)
{
int h=1,t=1; q[1]=j-1;// q[1]=0;
for(int i=j; i<=n; ++i)
{
while(h<t && Y(q[h+1],q[h])<=1ll*tm[i]*X(q[h+1],q[h])) ++h;
f[Now^1][i]=Calc(q[h],i,j); while(h<t && Y(i,q[t])*X(q[t],q[t-1])<=Y(q[t],q[t-1])*X(i,q[t])) --t;
q[++t]=i;
}
}
printf("%I64d\n",f[Now][n]);
}
}
inline LL Y(int j,int k){
return f[j]-f[k]+sum[j]-sum[k];
}
inline LL X(int j,int k){
return j-k;
}
inline LL Calc(int fr,int to){
return f[fr]+tm[to]*(to-fr)-sum[to]+sum[fr]+C;
}
void Solve()
{
f[0]=num[0]=0;
int h=1,t=1; q[1]=0;
for(int i=1; i<=n; ++i)
{
while(h<t && Y(q[h+1],q[h])<=tm[i]*X(q[h+1],q[h])) ++h;
f[i]=Calc(q[h],i), num[i]=num[q[h]]+1;
while(h<t && Y(i,q[t])*X(q[t],q[t-1])<=Y(q[t],q[t-1])*X(i,q[t])) --t;
q[++t]=i;
}
} int main()
{
freopen("plant.in","r",stdin);
freopen("plant.out","w",stdout); n=read(), K=read();
int s=0;
tm[1]=read(), read();
for(int i=2; i<=n; ++i) tm[i]=read()-(s+=read()); std::sort(tm+1,tm+1+n);
// int cnt=n; n=1;// WA!
// for(int i=2; i<=cnt; ++i) if(tm[i]!=tm[i-1]) tm[++n]=tm[i];
for(int i=1; i<=n; ++i) sum[i]=sum[i-1]+tm[i]; if(1ll*n*K<=2e7) {Spec::n=n, Spec::Main(); return 0;}
// Spec::n=n, Spec::Main(); return 0; LL l=sum[n]*n, r=-l;
if(l>r) std::swap(l,r);
while(l<=r){
if(C=l+r>>1, Solve(), num[n]>K) l=C+1;
else r=C-1;
}
C=l, Solve();
// C=r+1, Solve();
printf("%I64d\n",f[n]-C*K); return 0;
}

这是\(O(n^2k)\)暴力和\(O(nk)\)斜率优化,还有个改double的带权二分(开始拍出错tm[]爆int了),都去重了所以对拍虽然过了然而。。

就这题会所以特别不嫌麻烦。

暴力:

#include <cstdio>
#include <cctype>
#include <cstring>
#include <algorithm>
#define gc() getchar()
//#define int long long
typedef long long LL;
const int N=1e4+5; int n,K,tm[N];
LL sum[N],f[N][250]; inline int read()
{
int now=0;register char c=gc();
for(;!isdigit(c);c=gc());
for(;isdigit(c);now=now*10+c-'0',c=gc());
return now;
}
inline LL Calc(int fr,int to,int k){
return f[fr][k-1]+1ll*(to-fr)*tm[to]-sum[to]+sum[fr];
} int main()
{
freopen("plant.in","r",stdin);
// freopen("plant.out","w",stdout);
freopen("violence.out","w",stdout); n=read(), K=read();
int s=0;
tm[1]=read(), read();
for(int i=2; i<=n; ++i) tm[i]=read()-(s+=read()); // for(int i=1; i<=n; ++i) printf("%d:%d\n",i,tm[i]);
std::sort(tm+1,tm+1+n);
int cnt=n; n=1;
for(int i=2; i<=cnt; ++i) if(tm[i]!=tm[i-1]) tm[++n]=tm[i];
// for(int i=1; i<=n; ++i) printf("%d:%d\n",i,tm[i]);putchar('\n'); for(int i=1; i<=n; ++i) sum[i]=sum[i-1]+(LL)tm[i];
memset(f,0x7f,sizeof f);
f[0][0]=0;
for(int i=1; i<=n; ++i)
for(int j=1; j<=K; ++j)
for(int k=0; k<i; ++k)
f[i][j]=std::min(f[i][j],Calc(k,i,j));
printf("%I64d\n",f[n][K]); return 0;
}

裸斜率优化

#include <cstdio>
#include <cctype>
#include <cstring>
#include <algorithm>
#define gc() getchar()
typedef long long LL;
const int N=2e5+5; int n,K,Now,q[N];//longlong
LL tm[N],sum[N],f[2][N]; inline int read()
{
int now=0;register char c=gc();
for(;!isdigit(c);c=gc());
for(;isdigit(c);now=now*10+c-'0',c=gc());
return now;
}
inline LL Y(int j,int k){
return f[Now][j]-f[Now][k]+sum[j]-sum[k];
}
inline LL X(int j,int k){
return j-k;
}
inline LL Calc(int fr,int to,int k){
return f[Now][fr]+tm[to]*(to-fr)-sum[to]+sum[fr];
} int main()
{
freopen("plant.in","r",stdin);
// freopen("plant.out","w",stdout);
freopen("slope.out","w",stdout); n=read(), K=read();
int s=0;
tm[1]=read(), read();
for(int i=2; i<=n; ++i) tm[i]=read()-(s+=read()); std::sort(tm+1,tm+1+n);
int cnt=n; n=1;
for(int i=2; i<=cnt; ++i) if(tm[i]!=tm[i-1]) tm[++n]=tm[i]; for(int i=1; i<=n; ++i) sum[i]=sum[i-1]+tm[i];
memset(f,0x7f,sizeof f);
f[0][0]=0, Now=0;
for(int j=1; j<=K; ++j, Now^=1)
{
int h=1,t=1; q[1]=j-1;// q[1]=0;
for(int i=j; i<=n; ++i)
{
while(h<t && Y(q[h+1],q[h])<=tm[i]*X(q[h+1],q[h])) ++h;
f[Now^1][i]=Calc(q[h],i,j); while(h<t && Y(i,q[t])*X(q[t],q[t-1])<=Y(q[t],q[t-1])*X(i,q[t])) --t;
q[++t]=i;
}
}
printf("%I64d\n",f[Now][n]); return 0;
}

double带权二分。。:

//also right.
#include <cstdio>
#include <cctype>
#include <cstring>
#include <algorithm>
//#define gc() getchar()
#define eps (1e-2)
#define MAXIN 200000
#define gc() (SS==TT&&(TT=(SS=IN)+fread(IN,1,MAXIN,stdin),SS==TT)?EOF:*SS++)
typedef long long LL;
const int N=2e5+5; int n,K,tm[N],q[N],num[N];//longlong
LL sum[N];
double f[N],C;
char IN[MAXIN],*SS=IN,*TT=IN; inline int read()
{
int now=0;register char c=gc();
for(;!isdigit(c);c=gc());
for(;isdigit(c);now=now*10+c-'0',c=gc());
return now;
}
inline double Y(int j,int k){
return f[j]-f[k]+sum[j]-sum[k];
}
inline double X(int j,int k){
return j-k;
}
inline double Calc(int fr,int to){
return f[fr]+1.0*(to-fr)*tm[to]-(double)sum[to]+(double)sum[fr]+C;
}
void Solve()
{
f[0]=num[0]=0;
int h=1,t=1; q[1]=0;
for(int i=1; i<=n; ++i)
{
while(h<t && Y(q[h+1],q[h])<=1.0*tm[i]*X(q[h+1],q[h])) ++h;
f[i]=Calc(q[h],i), num[i]=num[q[h]]+1;
while(h<t && Y(i,q[t])*X(q[t],q[t-1])<=Y(q[t],q[t-1])*X(i,q[t])) --t;
q[++t]=i;
}
} int main()
{
freopen("plant.in","r",stdin);
// freopen("tmp.out","w",stdout); n=read(), K=read();
int s=0;
tm[1]=read(), read();
for(int i=2; i<=n; ++i) tm[i]=read()-(s+=read()); std::sort(tm+1,tm+1+n);
int cnt=n; n=1;
for(int i=2; i<=cnt; ++i) if(tm[i]!=tm[i-1]) tm[++n]=tm[i];
for(int i=1; i<=n; ++i) sum[i]=sum[i-1]+(LL)tm[i]; double l=1.0*sum[n]*n, r=-l;
if(l>r) std::swap(l,r);
while(r>l+eps){
if(C=(l+r)*0.5, Solve(), num[n]>K) l=C+1;
else r=C-1;
}
C=l, Solve();
// C=r+1, Solve();
printf("%I64d\n",(LL)(f[n]-C*K+0.5)); return 0;
}

6.13校内互测 (DP 带权二分 斜率优化)的更多相关文章

  1. 洛谷 4383 [八省联考2018]林克卡特树lct——树形DP+带权二分

    题目:https://www.luogu.org/problemnew/show/P4383 关于带权二分:https://www.cnblogs.com/flashhu/p/9480669.html ...

  2. 洛谷.4383.[八省联考2018]林克卡特树lct(树形DP 带权二分)

    题目链接 \(Description\) 给定一棵边带权的树.求删掉K条边.再连上K条权为0的边后,新树的最大直径. \(n,K\leq3\times10^5\). \(Solution\) 题目可以 ...

  3. Codeforces.739E.Gosha is hunting(DP 带权二分)

    题目链接 \(Description\) 有\(n\)只精灵,两种精灵球(高级和低级),每种球能捕捉到第\(i\)只精灵的概率已知.求用\(A\)个低级球和\(B\)个高级球能捕捉到精灵数的最大期望. ...

  4. DP的各种优化(动态规划,决策单调性,斜率优化,带权二分,单调栈,单调队列)

    前缀和优化 当DP过程中需要反复从一个求和式转移的话,可以先把它预处理一下.运算一般都要满足可减性. 比较naive就不展开了. 题目 [Todo]洛谷P2513 [HAOI2009]逆序对数列 [D ...

  5. P4383 [八省联考2018]林克卡特树lct 树形DP+凸优化/带权二分

    $ \color{#0066ff}{ 题目描述 }$ 小L 最近沉迷于塞尔达传说:荒野之息(The Legend of Zelda: Breath of The Wild)无法自拔,他尤其喜欢游戏中的 ...

  6. 洛谷P2619 [国家集训队2]Tree I(带权二分,Kruscal,归并排序)

    洛谷题目传送门 给一个比较有逼格的名词--WQS二分/带权二分/DP凸优化(当然这题不是DP). 用来解决一种特定类型的问题: 有\(n\)个物品,选择每一个都会有相应的权值,需要求出强制选\(nee ...

  7. BZOJ_4609_[Wf2016]Branch Assignment_决策单调性+带权二分

    BZOJ_4609_[Wf2016]Branch Assignment_决策单调性+带权二分 Description 要完成一个由s个子项目组成的项目,给b(b>=s)个部门分配,从而把b个部门 ...

  8. BZOJ_5311_贞鱼_决策单调性+带权二分

    BZOJ_5311_贞鱼_决策单调性+带权二分 Description 众所周知,贞鱼是一种高智商水生动物.不过他们到了陆地上智商会减半. 这不?他们遇到了大麻烦! n只贞鱼到陆地上乘车,现在有k辆汽 ...

  9. HDU 4359 Easy Tree DP? 带权二叉树的构造方法 dp

    题意: 给定n deep 1.构造一个n个节点的带权树,且最大深度为deep,每一个节点最多仅仅能有2个儿子 2.每一个节点的值为2^0, 2^1 ··· 2^(n-1)  随意两个节点值不能同样 3 ...

随机推荐

  1. “榕树下·那年”移动app ( hybrid ) 开发总结

        榕树下网站本身的技术人员并不多,所以app开发的任务就到了母公司盛大文学这边.       盛大文学无线业务中心负责这次具体开发任务.       一如既往的,开发的情况是:时间紧,任务重,人 ...

  2. python3之pymysql模块

    1.python3 MySQL数据库链接模块 PyMySQL 是在 Python3.x 版本中用于连接 MySQL 服务器的一个库,Python2中则使用mysqldb. PyMySQL 遵循 Pyt ...

  3. go 匿名函数和闭包

    匿名函数 1. 函数也是一种类型,因此可以定义作为一个函数类型的变量 package main import "fmt" // 函数作为参数 func add(a, b int) ...

  4. Oracle 函数 “把当前的用户(审核人,审核通过后)插入到数据表中”

    create or replace function mcode_apply_update_personnel(p_mca_no VARCHAR2, -- 参数(实参) p_action VARCHA ...

  5. java 闭包与回调

    闭包(closure)是一个可调用的对象,它记录了一些信息,这些信息来自于创建它的作用域. 内部类是面向对象的闭包,因为它不仅包含外围类对象(创建内部类的作用域)的信息,还自动拥有一个指向此外围类对象 ...

  6. javaweb笔记二

    web服务器:实现服务器的开启,监听端口,接收客户端请求,产生响应.响应信息只能是静态的HTML,缺乏灵活性.web容器:是辅助应用的一种方式,是为了解决web服务器缺陷而产生的.可以将请求信息处理完 ...

  7. TIAGo ROS模拟教程2 - 自主机器人导航

    TIAGo ROS Simulation Tutorial 2 – Autonomous robot navigation TIAGo ROS模拟教程2 - 自主机器人导航 发表于 12月 23,20 ...

  8. NFS服务简介

    NFS服务简介 NFS是Network File System的缩写,即网络文件系统.NFS是由Sun开发并发展起来的一项用于在不同机器,不同操作系统之间通过网络互相分享各自的文件.NFS serve ...

  9. SQL SERVER 断开所有连接(转)

    通过sql server management studio对数据进行管理,比如数据库改名等,经常遇到有正在运行的连接,以致无法操作,这时候断掉所有的连接很有必要.代码如下:(会断掉某个库的所有连接, ...

  10. 在 SQL Server 2005 中配置数据库邮件

    一.            SQL Server发邮件原理和组件介绍: 数据库邮件有4个组件:配置文件.邮件处理组件.可执行文件以及“日志记录和审核组件”. l  配置组件包括: 1)数据库邮件帐户包 ...