hdu多校第一场1003 (hdu6580)Milk 背包
题意:
有一个n*m的矩阵,左右可以随便走,但只能在每一行的中点往下走,每走一格花费时间1.
现在这个矩阵里放了k瓶牛奶,第i个牛奶喝下去需要ti时间
起点是(1,1)
对于每个i∈[1,k],问喝掉k瓶牛奶花费的最小时间
题解:
首先离散化行。
记第 i 行的牛奶数为 ci,则对于第 i 行,求出在行内向左/右走喝 1,2,...,ci 包牛奶并 且回到/不回到行中点的最短时间,然后合并背包求出在第 i 行内喝 1,2,...,ci 包牛奶并且 回到/不回到行中点的最短时间,然后和在前 i−1 行喝牛奶并回到中点的背包合并,求出 在前 i 行内喝 1,2,...,k 包牛奶并且回到/不回到行中点的最短时间,并用不回到中点的背包 更新答案。每一行处理的复杂度为 O(kci),因此总复杂度为 O(k2)。
注意对第一行因为是从最左边而不是中间开始,所以要特殊处理。
#include<bits/stdc++.h>
#define MAXN 10004
#define LL long long
#define INF 0x3f3f3f3f3f3f3f3f
using namespace std;
struct Milk{
int x,y,t;
friend bool operator >(const Milk &a,const Milk &b){
return a.y>b.y;
}
friend bool operator <(const Milk &a,const Milk &b){
return a.y<b.y;
} Milk(){}
Milk(int a,int b,int c){
x=a;y=b;t=c;
}
}milk[MAXN];
vector<LL> solve(const vector<Milk> &a,int dest){
//调用引用,减小常数
//背包算出停在dest点花费最小时间
//若dest为0则不限制停在哪一点
vector<LL> c(a.size(),INF);
vector<LL> t(a.size(),INF);
c[]=(dest==-)?:abs(dest-a[].y);
t[]=;
for(int i=;i<a.size();++i){
int len=abs(a[i].y-a[i-].y);
for(int j=;j<i;++j)t[j]+=len;
for(int j=i;j>=;--j)t[j]=min(t[j],t[j-]+a[i].t);
for(int j=;j<=i;++j){
LL tmp=t[j]+(dest==-?:abs(dest-a[i].y));
c[j]=min(c[j],tmp);
}
}
return c;
}
vector<LL> Merge(const vector<LL> &a,const vector<LL> &b){
vector<LL> c(a.size()+b.size()-,INF);
for(int i=;i<a.size();++i){
for(int j=;j<b.size();++j){
c[i+j]=min(c[i+j],a[i]+b[j]);
}
}
//两个参数分别是朝向两个方向喝多少瓶牛奶花费最少时间,把这俩合并
return c;
}
int main(){
int T;
scanf("%d",&T);
while(T--){
int n,m,k;
scanf("%d %d %d",&n,&m,&k);
vector<int> disc;
disc.push_back();
for(int i=;i<=k;i++){
scanf("%d %d %d",&milk[i].x,&milk[i].y,&milk[i].t);
disc.push_back(milk[i].x);
}
sort(disc.begin(),disc.end());
disc.erase(unique(disc.begin(),disc.end()),disc.end());
//去重
vector<Milk> a[MAXN];
LL Ans[MAXN];
for(int i=;i<disc.size();++i)a[i].clear(); for(int i=;i<=k;++i){
int tmp=lower_bound(disc.begin(),disc.end(),milk[i].x)-disc.begin();
a[tmp].push_back(milk[i]);
Ans[i]=INF;
}
//将行离散化
for(int i=;i<disc.size();++i){
sort(a[i].begin(),a[i].end());
}
vector<LL> f[];//存储结果
vector<Milk> t=a[];//存储当前行 t.insert(t.begin(),Milk(,,)); f[]=solve(t,(m+)/);
vector<LL> g=solve(t,-);
for(int i=;i<t.size();++i)Ans[i]=min(Ans[i],g[i]); for(int i=;i<disc.size();++i) {
vector<Milk>::iterator sp=lower_bound(a[i].begin(),a[i].end(),Milk(i,(m+)/,));
vector<Milk> t0(a[i].begin(),sp);
vector<Milk> t1(sp,a[i].end()); t0.push_back(Milk(i,(m+)/,));
reverse(t0.begin(),t0.end()); t1.insert(t1.begin(),Milk(i,(m+)/,)); vector<LL> f0,f1,g0,g1;
f0=solve(t0,(m+)/);
f1=solve(t1,(m+)/);
g0=solve(t0,-);
g1=solve(t1,-);
//向两个方向分别背包 g0=Merge(f1,g0);
g1=Merge(f0,g1); vector<LL> g(g0.size()); for(int j=;j<g.size();++j){
g[j]=min(g0[j],g1[j]);
} g=Merge(f[(i-)&],g);
//把每层的背包合并 f[i&]=Merge(f[(i-)&],Merge(f0,f1)); for(int j=;j<g.size();++j) {
Ans[j]=min(Ans[j],g[j]+=disc[i]-disc[i-]);
f[i&][j]+=disc[i]-disc[i-];
}
} for(int i=;i<k;i++){
printf("%lld ",Ans[i]);
}
printf("%lld\n",Ans[k]);
}
}
hdu多校第一场1003 (hdu6580)Milk 背包的更多相关文章
- hdu 6035:Colorful Tree (2017 多校第一场 1003) 【树形dp】
题目链接 单独考虑每一种颜色,答案就是对于每种颜色至少经过一次这种的路径条数之和.反过来思考只需要求有多少条路径没有经过这种颜色即可. 具体实现过程比较复杂,很神奇的一个树形dp,下面给出一个含较详细 ...
- hdu 多校第一场
1001 思路:打表可以发现只有3|n 和 4|n 的情况有解,判一下就好啦. #include<bits/stdc++.h> #define LL long long #define f ...
- hdu多校第一场 1006 (hdu6583)Typewriter dp/后缀自动机
题意: 有个打字机,在当前字符串后新加一个字花费p,把当前字符串的一个连续子串拷贝到当前字符串的末尾花费q,给定一个字符串,求用打字机打出这个字符串的最小花费. 题解: 容易想到用dp 记dp[i]为 ...
- hdu多校第一场1005(hdu6582)Path 最短路/网络流
题意: 在无向图上删边,让此图上从起点到终点的最短路长度变大,删边的代价是边长,求最小代价. 题解: 先跑一遍迪杰斯特拉,求出所有点的d[]值,然后在原图上保留所有的边(i,j)仅当i,j满足d[j] ...
- hdu多校第一场1004(hdu6581)Vacation 签到
题意:有n+1辆车,每辆车都有一定的长度,速度和距离终点的距离,第1-n辆车在前面依次排列,第0辆车在最后面.不允许超车,一旦后车追上前车,后车就减速,求第0辆车最快什么时候能到达终点? 思路:对于每 ...
- hdu多校第一场 1013(hdu6590)Code 凸包交
题意: 给定一组(x1,x2,y),其中y为1或0,问是否有一组(w1,w2,b),使得上述的每一个(x1,x2,y)都满足x1*w1+x2*w2+b在y=1时大于0,在y=-1时小于0. 题解: 赛 ...
- HDU6581 Vacation (HDU2019多校第一场1004)
HDU6581 Vacation (HDU2019多校第一场1004) 传送门:http://acm.hdu.edu.cn/showproblem.php?pid=6581 题意: 给你n+1辆汽车, ...
- 2019牛客多校第一场 I Points Division(动态规划+线段树)
2019牛客多校第一场 I Points Division(动态规划+线段树) 传送门:https://ac.nowcoder.com/acm/contest/881/I 题意: 给你n个点,每个点有 ...
- 牛客多校第一场 B Inergratiion
牛客多校第一场 B Inergratiion 传送门:https://ac.nowcoder.com/acm/contest/881/B 题意: 给你一个 [求值为多少 题解: 根据线代的知识 我们可 ...
随机推荐
- usleep - 睡眠若干微秒
总览 (SYNOPSIS) usleep [number] 描述 (DESCRIPTION) usleep 睡眠 指定的 微秒数. 缺省值 是 1. 选项 (OPTIONS) --usage 显示 简 ...
- 微信小程序之自定义组件
在微信小程序项目中 肯定会存在很多功能和样式上相似的部分 面对这种情况 只是单单的ctrl+c ctrl+v 就显得很low了,而且也不便于后期维护那么这时候 使用微信小程序中的自定义组件功能就很合适 ...
- html标签注意事项
1,关于媒体的video标签 在同一个页面上如果有多个video标签,并且初始化都赋值,则video不会播放, 解决办法,用计时器每隔50ms给后面的video标签设置src,设置完为止 2,关于ch ...
- JS自定义Array原型移除函数
<script type="text/javascript"> //删除元素值 Array.prototype.remove = function(element){ ...
- 理解TCP/IP,SOCKET,HTTP,FTP,RMI,RPC,webservic
TCP/IP:网络宽带,传输数据的基础协议,所有得数据要在网络上传输都是基于TCP/IP协议(或UDP),才能送达到指定的目的地(IP,服务器硬件地址). SOCKET:SOCKET只是面对编程人员的 ...
- bzoj1025题解
[题意分析] 定义一个等价类为满足如下条件的一个极大的集合Q:∀t∈Q,k∈N+,若tk∈全集R,都成立tk∈Q. 给定n,记[1,n]∩N上所有排列置换的全集为R.求对于所有的等价类Q,card({ ...
- C/C++:Windows编程—调用DLL程序的2种方法(转载)
文章为转载,原文出处https://blog.csdn.net/qq_29542611/article/details/86618902 前言先简单介绍下DLL.DLL:Dynamic Link Li ...
- 9.RabbitMQ Topic类型交换机
RabbitMQ消息服务中Topic类型交换机根据通配符路由消息,*代表一个单词,#代表代表0或多个单词. 生产者 消费者 代码 Producer.java package com.tes ...
- ionic:目录
ylbtech-ionic:目录 1.返回顶部 1. http://www.runoob.com/ionic/ionic-tutorial.html 2. 2.返回顶部 3.返回顶部 4.返回 ...
- mysql查看数据库大小或者表大小
要想知道每个数据库的大小的话,步骤如下: 1.进入information_schema 数据库(存放了数据库的信息) use information_schema; 2.查询所有数据库的大小: sel ...