Bzoj3352 [ioi2009]旅行商
Time Limit: 20 Sec Memory Limit: 128 MB
Submit: 89 Solved: 36
Description
Input
Output
Sample Input
2 80 100
20 125 130
10 75 150
5 120 110
Sample Output
HINT
Source
动态规划 线性dp 线段树优化
设 $f[i][j]$ 表示第 i 天停在j号展会位置时的最大收益。
显然有 $ f[i][j] = max{f[i-1][k] * cost(k,j)}+ w[j] $
注意到天数和展会数同级,可以认为多数展会不在同一天,这时可以把第一维i丢掉。
丢掉以后空间够了,时间复杂度还是太高啊?
我们把cost展开,当顺流而下的时候,假设向i转移的时候,j位置比k位置优,有:
$$ f[j] - (L_i-L_j) * D > f[k] - (L_i-L_k) * D $$
$$ f[j]+L_j*D > f[k] + L_k*D $$
把$ f[j]+L_j*D $ 丢进线段树里,维护区间最大值即可$O(logn)$查询。
逆流而上同理。
当一些展会挤在同一天的时候怎么处理?
撕烤一下可以发现同一天经过的展会一定是一个连续的区间(从一点到另一点的时候如果中途经过别的展会,不拿白不拿)。
对于每一个终点,分类讨论起点在上游还是下游,枚举起点找最大收益,这样显然是正确的。
维护two-pointers或者前缀最大值即可快速转移。
78行的初始化边界没有加,WA*2
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<cmath>
using namespace std;
const int INF=0x3f3f3f3f;
const int mxn=;
int read(){
int x=,f=;char ch=getchar();
while(ch<'' || ch>''){if(ch=='-')f=-;ch=getchar();}
while(ch>='' && ch<=''){x=x*+ch-'';ch=getchar();}
return x*f;
}
int n,m,D,U,S;
struct met{
int day,x;
int w;
bool operator < (const met &b)const{
return (day==b.day && x<b.x) || day<b.day;
}
}a[mxn];
int f[mxn];
int tmp[mxn],tmp2[mxn];
//
struct node{
int mxu,mxd;
}t[mxn<<];
#define ls rt<<1
#define rs rt<<1|1
inline void pushup(int rt){
t[rt].mxd=max(t[ls].mxd,t[rs].mxd);
t[rt].mxu=max(t[ls].mxu,t[rs].mxu);
return;
}
void Build(int l,int r,int rt){
if(l==r){t[rt].mxd=t[rt].mxu=-INF;return;}
int mid=(l+r)>>;
Build(l,mid,ls);Build(mid+,r,rs);
pushup(rt);
return;
}
void update(int p,int l,int r,int rt){
if(l==r){
t[rt].mxd=f[p]+a[p].x*D; t[rt].mxu=f[p]-a[p].x*U;
return;
}
int mid=(l+r)>>;
if(a[p].x<=mid)update(p,l,mid,ls);
else update(p,mid+,r,rs);
pushup(rt);
return;
}
//
int MXU,MXD;
void query(int L,int R,int l,int r,int rt){
if(L<=l && r<=R){
MXD=max(t[rt].mxd,MXD);MXU=max(t[rt].mxu,MXU);
return;
}
int mid=(l+r)>>;
if(L<=mid)query(L,R,l,mid,ls);
if(R>mid)query(L,R,mid+,r,rs);
return;
}
void solve(){
Build(,m,);
update(,,m,);
for(int i=,j;i<=n;i=j+){
for(j=i;a[j].day==a[i].day;j++){
f[j]=-INF;
MXU=-INF; query(a[j].x,m,,m,);
f[j]=max(f[j],MXU+a[j].x*U);
MXD=-INF; query(,a[j].x,,m,);
f[j]=max(f[j],MXD-a[j].x*D);
f[j]+=a[j].w;
}j--;
tmp[i]=f[i];tmp2[j]=f[j];
for(int k=i+;k<=j;k++)
tmp[k]=max(f[k],tmp[k-]-(a[k].x-a[k-].x)*D+a[k].w);
for(int k=j-;k>=i;k--)
tmp2[k]=max(f[k],tmp2[k+]-(a[k+].x-a[k].x)*U+a[k].w);
for(int k=i;k<=j;k++){
f[k]=max(f[k],max(tmp[k],tmp2[k]));
update(k,,m,);
}
}
printf("%d\n",f[n]);
return;
}
int main(){
int i,j;
n=read();
U=read();D=read();
S=read();
a[]=(met){,S,};n++;
for(i=;i<=n;i++){
a[i].day=read();a[i].x=read();a[i].w=read();
m=max(m,a[i].x);
}
sort(a+,a+n+);++n;
a[n]=(met){a[n-].day+,S,};
m=max(m,S);
solve();
return ;
}
Bzoj3352 [ioi2009]旅行商的更多相关文章
- 【C#代码实战】群蚁算法理论与实践全攻略——旅行商等路径优化问题的新方法
若干年前读研的时候,学院有一个教授,专门做群蚁算法的,很厉害,偶尔了解了一点点.感觉也是生物智能的一个体现,和遗传算法.神经网络有异曲同工之妙.只不过当时没有实际需求学习,所以没去研究.最近有一个这样 ...
- 洛谷P1782 旅行商的背包[多重背包]
题目描述 小S坚信任何问题都可以在多项式时间内解决,于是他准备亲自去当一回旅行商.在出发之前,他购进了一些物品.这些物品共有n种,第i种体积为Vi,价值为Wi,共有Di件.他的背包体积是C.怎样装才能 ...
- 2016全国研究生数学建模A题多无人机协同任务规划——基于分布式协同多旅行商MTSP遗传算法
MTSP问题是指:有Ⅳ个城市,要求旅行商到达每个城市各一次,且仅一次,并[旦 1到起点,且要求旅行路线最短.而多旅行商问题M个旅行商从同一个城市(或多个城市)出发.分羽走一条旅路线,且总路程缀短.有关 ...
- [vijos P1014] 旅行商简化版
昨天早上上课讲旅行商问题,有点难,这周抽空把3^n的算法码码看.不过这个简化版已经够折腾人了. 其一不看解析不知道这是双进程动态规划,不过我看的解析停留在f[i,j]表示第一个人走到i.第二个人走到j ...
- vijosP1014 旅行商简化版
vijosP1014 旅行商简化版 链接:https://vijos.org/p/1014 [思路] 双线DP. 设ab,ab同时走.用d[i][j]表示ab所处结点i.j,且定义i>j,则有转 ...
- 洛谷【P1523】旅行商的背包(算法导论 15-1) 题解
P1523 旅行商简化版 题目背景 欧几里德旅行商\((Euclidean Traveling Salesman)\)问题也就是货郎担问题一直是困扰全世界数学家.计算机学家的著名问题.现有的算法都没有 ...
- hdu 4281 Judges' response(多旅行商&DP)
Judges' response Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) ...
- 旅行商(sale)
旅行商(sale) 题目描述 camp国有n座城市,由1,2,-,n编号.城市由n–1条双向道路相连.任意两个城市之间存在唯一的道路连通.有m个旅行商,第i个旅行商会从城市ai旅行到城市bi,贩卖ci ...
- 洛谷P1523 旅行商简化版(DP)
题目: P1523 旅行商简化版 解析 可以看做是两个人同时从西往东走,经过不一样的点,走到最东头的方案数 设\(f[i][j]\)表示一个人走到i,一个人走到j的最短距离(\(i<j\)) 第 ...
随机推荐
- PAT 甲级 1141 PAT Ranking of Institutions
https://pintia.cn/problem-sets/994805342720868352/problems/994805344222429184 After each PAT, the PA ...
- dividend = Integer.parseInt(args[0])参数问题
先来一段代码: package yichang; public class MyExceptionTest { public static void main(String[] args) { int ...
- DBGridEH序号的自动生成
序号的自动生成1.定义变量 private maxno:integer; public bmodified:boolean;2.写函数 function max(c ...
- Augmenting DOM Storage with IE's userData behavior
http://www.javascriptkit.com/javatutors/domstorage2.shtml Augmenting DOM Storage with IE's userData ...
- python3+selenium 牛刀小试
# coding:utf-8 # __author__ = 'Carry' import unittest from selenium import webdriver import time cla ...
- python的N个小功能(找到要爬取的验证码链接,并大量下载验证码样本)
# -*- coding: utf-8 -*- """ Created on Mon Mar 21 11:04:54 2017 @author: sl "&qu ...
- 【uoj#311】[UNR #2]积劳成疾 dp
题目描述 一个长度为 $n$ 的序列,每个数在 $[1,n]$ 之间.给出 $m$ ,求所有序列的 $\prod_{i=1}^{n-m+1}(\text{Max}_{j=i}^{j+m-1}a[j]) ...
- Candies CodeForces - 991C(二分水题)
就是二分暴力就好了 为什么要记下来 呵呵....emm你说为什么... 行吧 好吧 我一直以为我的二分出问题了 原来不是 依旧很帅 统计的时候求的减了多少次 然后用次数乘了mid 这样做会使那个人获 ...
- Android Studio自动生成UML关系类图
android studio 根据源码自动生成UML的插件介绍http://www.jianshu.com/p/cbccd831cf01 simpleumlhttps://plugins.jetbra ...
- 【bzoj4337】【Bjoi2015】树的同构
题解 无标号树的HASH: 找到树的重心,以重心为根求出括号序列: 由于树的重心最多只有两个,取字典序的最小括号序列HASH即可 树的括号序列$s_{u}="(s_{v_{1}},s_{v_ ...