题目描述

约翰开车来到镇上,他要带 KKK 吨饲料回家。运送饲料是需要花钱的,如果他的车上有 XXX 吨饲料,每公里就要花费 X2X^2X2 元,开车D公里就需要 D×X2D\times X^2D×X2 元。约翰可以从 NNN 家商店购买饲料,所有商店都在一个坐标轴上,第 iii 家店的位置是 XiX_iXi​ ,饲料的售价为每吨 CiC_iCi​ 元,库存为 FiF_iFi​ 。

约翰从坐标 X=0X=0X=0 开始沿坐标轴正方向前进,他家在坐标 X=EX=EX=E 上。为了带 KKK 吨饲料回家,约翰最少的花费是多少呢?假设所有商店的库存之和不会少于 KKK 。

举个例子,假设有三家商店,情况如下所示:

坐标 X=1X=1X=1 X=3X=3X=3 X=4X=4X=4 E=5E=5E=5
库存 111 111 111
售价 111 222 222

如果 K=2K=2K=2 ,约翰的最优选择是在离家较近的两家商店购买饲料,则花在路上的钱是 1+4=51+4=51+4=5 ,花在商店的钱是 2+2=42+2=42+2=4 ,共需要 999 元。

输入输出格式

输入格式:

第 111 行:三个整数 K,E,NK,E,NK,E,N 第 2..N+12..N+12..N+1 行:第 i+1i+1i+1 行的三个整数代表, Xi,Fi,CiX_i,F_i,C_iXi​,Fi​,Ci​ .

输出格式:

一个整数,代表最小花费

输入输出样例

输入样例#1:

2 5 3
3 1 2
4 1 2
1 1 1
输出样例#1:

9

提交地址:Luogu4544;

我们发现, 最优的情况肯定是从家里往前走,走到要到达想要到的最远的商店, 往回走的时候再买东西;
这就提示我们, 我们要先对坐标排序, 然后设dp[i][j],表示到了第i个商店, 在第i个商店之前买了j个东西的最小花费;
dp[i][j]=min(dp[i-1][p]+dis[i]*j*j+w[i-1]*(j-p));
什么意思呢?
我们枚举一个p, 表示第i-1个商店时有p个货物,那么显然在i-1个商店买了(j-p)个货物,算上在第i-1个商店的花费,加上从i-1到i的路费,就是dp[i][j];
复杂度nk^2, 妥妥的炸;
考虑优化;
发现转移式子里有min,自觉地想到了单调队列;
我们对式子进行一波变形。
dp[i-1][p] - w[i-1]*p + dis[i]*j*j + w[i-1]*j;
我们发现, 在i和j变化的时候,只有p是在变的,所以我们单调队列里放p;
怎么处理呢?
如果(j-q.front() > F[i-1])就pop掉队首, 因为我们要在i-1商店买的货物大于了第i-1个店的库存;
如果o=q.back(), dp[i-1][o]-w[i-1]*o >= dp[i-1][j]-w[i-1]*j, 就pop掉队尾;显然;
(写反了这个↑还能A, 数据太水了)
要注意的是,要把自己的家也当成一个点,这样dp[n][k]才是最后的答案!
然后注意开long long;
Code:
 #include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
using namespace std;
#define int long long inline int read()
{
int res=;bool fl=;char ch=getchar();
while(!isdigit(ch)){if(ch=='-')fl=;ch=getchar();
}while(isdigit(ch)){res=(res<<)+(res<<)+(ch-'');ch=getchar();
}return fl?-res:res;
} int n, k, e; struct date
{
int pos;
int F;
int w;
friend bool operator <(date a, date b)
{
return a.pos < b.pos;
}
}fam[]; int dp[][]; signed main()
{
k = read(), e = read(), n = read(); for (register int i = ; i <= n ; i ++)
{
fam[i].pos = read(), fam[i].F = read(), fam[i].w = read();
} fam[++n] = (date){e, , }; sort(fam + , fam + + n); memset(dp, 0x3f, sizeof dp); dp[][] = ; for (register int i = ; i <= n ; i ++)
{
deque <int> q;
for (register int j = ; j <= k ; j ++)
{
while (!q.empty() and j - q.front() > fam[i-].F) q.pop_front(); //要买的大于上一个店的存储
if (dp[i-][j] != 0x3f3f3f3f)
{
while (!q.empty() and dp[i-][q.back()] - fam[i-].w * q.back() >= dp[i-][j] - fam[i-].w * j) q.pop_back();
q.push_back(j);
}
int o = q.front();
if (!q.empty()) dp[i][j] = dp[i-][o] - fam[i-].w * o + (fam[i].pos - fam[i-].pos) * j * j + fam[i-].w * j;
}
} cout << dp[n][k] << endl;
return ; }

 

[USACO10NOV]购买饲料Buying Feed 单调队列优化DP的更多相关文章

  1. P4544 [USACO10NOV]购买饲料Buying Feed

    额,直接思路就dp吧.(我还想了想最短路之类的233但事实证明不行2333.....) 直入主题: 化简题意:在x轴上有n个点,坐标为xi.从原点出发,目标点为e,在途中需要收集K重量的物品,在每个点 ...

  2. 【luoguP4544】[USACO10NOV]购买饲料Buying Feed

    题目链接 首先把商店按坐标排序 \(dp_{i,j}\)表示前i个商店买了j吨饲料并运到终点的花费,二进制拆分优化转移 #include<algorithm> #include<io ...

  3. 【bzoj1855】 [Scoi2010]股票交易 单调队列优化DP

    上一篇blog已经讲了单调队列与单调栈的用法,本篇将讲述如何借助单调队列优化dp. 我先丢一道题:bzoj1855 此题不难想出O(n^4)做法,我们用f[i][j]表示第i天手中持有j只股票时,所赚 ...

  4. 1855: [Scoi2010]股票交易[单调队列优化DP]

    1855: [Scoi2010]股票交易 Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 1083  Solved: 519[Submit][Status] ...

  5. 单调队列优化DP——习题收集

    前言 感觉可以用单调队列优化dp的模型还是挺活的,开个随笔记录一些遇到的比较有代表性的模型,断续更新.主要做一个收集整理总结工作. 记录 0x01 POJ - 1821 Fence,比较适合入门的题, ...

  6. 单调队列优化DP,多重背包

    单调队列优化DP:http://www.cnblogs.com/ka200812/archive/2012/07/11/2585950.html 单调队列优化多重背包:http://blog.csdn ...

  7. bzoj1855: [Scoi2010]股票交易--单调队列优化DP

    单调队列优化DP的模板题 不难列出DP方程: 对于买入的情况 由于dp[i][j]=max{dp[i-w-1][k]+k*Ap[i]-j*Ap[i]} AP[i]*j是固定的,在队列中维护dp[i-w ...

  8. hdu3401:单调队列优化dp

    第一个单调队列优化dp 写了半天,最后初始化搞错了还一直wa.. 题目大意: 炒股,总共 t 天,每天可以买入na[i]股,卖出nb[i]股,价钱分别为pa[i]和pb[i],最大同时拥有p股 且一次 ...

  9. Parade(单调队列优化dp)

    题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=2490 Parade Time Limit: 4000/2000 MS (Java/Others)    ...

随机推荐

  1. 自定义 behavior - 完美仿 QQ 浏览器首页,美团商家详情页

    使用CoordinatorLayout打造各种炫酷的效果 自定义Behavior -- 仿知乎,FloatActionButton隐藏与展示 NestedScrolling 机制深入解析 一步步带你读 ...

  2. 手撸基于swoole 的分布式框架 实现分布式调用(20)讲

    最近看的一个swoole的课程,前段时间被邀请的参与的这个课程 比较有特点跟一定的深度,swoole的实战教程一直也不多,结合swoole构建一个新型框架,最后讲解如何实现分布式RPC的调用. 内容听 ...

  3. NLP舞动之中文分词浅析(一)

    一.简介        针对现有中文分词在垂直领域应用时,存在准确率不高的问题,本文对其进行了简要分析,对中文分词面临的分词歧义及未登录词等难点进行了介绍,最后对当前中文分词实现的算法原理(基于词表. ...

  4. maven引入本地jar包的方法

    maven作为包管理工具,好处不必多说 但是有些情况,比如需要引入第三方包,如快递鸟,支付宝,微信等jar包(当然有可能直接提供maven依赖) 如果直接下载到本地之后,怎么整合到自己的maven工程 ...

  5. 上手Dubbo之 环境搭建

    和传统ssm整合--写XML配置文件 搭建服务的提供者和服务的消费者,实现服务消费者跨应用远程调用服务提供者 公共模块抽取 公共模块的抽取 服务的消费者远程调用服务的提供者, 最起码他自己要得到在服务 ...

  6. DirectX12 3D 游戏开发与实战第二章内容

    矩阵代数 学习目标 理解矩阵及其相关运算的定义 探究为何能把向量和矩阵的乘法视为一种线性组合 学习单位矩阵.转置矩阵.行列式以及矩阵的逆等概念 逐步熟悉DirectXMath库中提供的关于矩阵计算的类 ...

  7. 微信小程序开发简述

    微信小程序简述 什么是微信小程序? 微信小程序,简称小程序,英文名Mini Program,是一种不需要下载安装即可使用的应用,它实现了应用“触手可及”的梦想,用户扫一扫或搜一下即可打开应用.全面开放 ...

  8. 不知道如何实现服务的动态发现?快来看看 Dubbo 是如何做到的

    上篇文章如果有人问你 Dubbo 中注册中心工作原理,就把这篇文章给他大致了解了注册中心作用以及 Dubbo Registry 模块源码,这篇文章将深入 Dubbo ZooKeeper 模块,去了解如 ...

  9. 《HelloGitHub》第 42 期

    兴趣是最好的老师,HelloGitHub 就是帮你找到兴趣! 简介 分享 GitHub 上有趣.入门级的开源项目. 这是一个面向编程新手.热爱编程.对开源社区感兴趣 人群的月刊,月刊的内容包括:各种编 ...

  10. GStreamer基础教程08 - 多线程

    摘要 GStreamer框架会自动处理多线程的逻辑,但在某些情况下,我们仍然需要根据实际的情况自己将部分Pipeline在单独的线程中执行,本文将介绍如何处理这种情况. GStreamer多线程 GS ...