题目描述

约翰开车回家,又准备顺路买点饲料了(咦?为啥要说“又”字?)回家的路程一共有 E 公里,
这一路上会经过 N 家商店,第 i 家店里有 F i 吨饲料,售价为每吨 C i 元。约翰打算买 K 吨饲料,他
知道商家的库存是足够的,至少所有店的库存总和不会少于 K。除了购买饲料要钱,运送饲料也是
要花油钱的,约翰的卡车上如果装着 X 吨饲料,那么他行驶一公里会花掉 X2 元,行驶 D 公里需要
DX2 元。已知第 i 家店距约翰所在的起点有 X i 公里,那么约翰在哪些商店买饲料运回家,才能做到
最省钱呢?

输入

• 第一行:三个整数 K,E 和 N,1 ≤ K ≤ 10000,1 ≤ E ≤ 500,1 ≤ N ≤ 500
• 第二行到第 N + 1 行:第 i + 1 行有三个整数 X i ,F i 和 C i ,0 < X i < E,1 ≤ F i ≤ 10000,1 ≤
C i ≤ 10 7

输出

• 单个整数:表示购买及运送饲料的最小费用

样例输入

2 5 3 3 1 2 4 1 2 1 1 1

样例输出

9

提示

在离家较近的两家商店里各购买一吨饲料,
则花在路上的钱是 1 + 4 = 5,花在店里的钱是
2 + 2 = 4
 
 
题解:
这题需要一种奇怪的思想:我们知道一顿饲料如果买了,必将一直影响到最后,于是我们将后来的消费就算到状态里去
于是可以定义f[i][j]表示前i个买j吨一直到终点的花费.然后发现可以消维.
保留f[j]即可  
定义d[i]为i到终点的距离.
f[j]=min(f[k]+j^2*d[i]-k^2*d[i]+j*F[i])
把k有关的全部都移项移出来,就可以放到单调队列里
 
单调队列动规:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=,M=;
typedef long long ll;
struct node
{
ll x,w,v;
}a[N];
ll f[M],q[M],id[M];
bool comp(const node &p,const node &q){return p.x<q.x;}
int main()
{
int n,m,e;
scanf("%d%d%d",&m,&e,&n);
for(int i=;i<=n;i++)scanf("%lld%lld%lld",&a[i].x,&a[i].w,&a[i].v);
sort(a+,a+n+,comp);
for(int i=;i<=n;i++)a[i].x=e-a[i].x;
for(int i=;i<=m;i++)f[i]=2e16;
f[]=;
ll tmp;int l,r;
for(int i=;i<=n;i++)
{
l=r=;q[l]=;id[l]=;
for(int j=;j<=m;j++)
{
while(l<r && j-id[l]>a[i].w)l++;
tmp=f[j];
f[j]=min(f[j],q[l]+j*j*a[i].x+j*a[i].v);
while(l<=r && tmp-j*j*a[i].x-j*a[i].v<=q[r])r--;
q[++r]=tmp-j*j*a[i].x-j*a[i].v;id[r]=j;
}
}
printf("%lld\n",f[m]);
return ;
}

70分暴力动规:

 #include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
const int N=,M=;
const ll xy=2e15;
struct node
{
int w,v,x;
}a[N];
ll F[N][M];
bool comp(const node &p,const node &q){return p.x<q.x;}
int main()
{
freopen("pp.in","r",stdin);
int n,m,e;
scanf("%d%d%d",&m,&e,&n);
for(int i=;i<=n;i++)scanf("%d%d%d",&a[i].x,&a[i].w,&a[i].v);
a[++n].x=e;
sort(a+,a+n+,comp);
for(int i=;i<=n;i++)for(int j=;j<=m;j++)F[i][j]=xy;
F[][]=;
ll now;int tmp;
for(int i=;i<=n;i++)
{
for(int j=;j<=m;j++)
{
tmp=j-a[i].w>=?j-a[i].w:;
if(F[i-][tmp]==xy)break;
for(int k=tmp;k<=j;k++)
{
now=F[i-][k]+k*k*(a[i].x-a[i-].x)+a[i].v*(j-k);
if(now<F[i][j])F[i][j]=now;
}
}
}
printf("%lld\n",F[n][m]);
}

【USACO】又买饲料 单调队列dp的更多相关文章

  1. POJ 3017 单调队列dp

    Cut the Sequence Time Limit: 2000MS   Memory Limit: 131072K Total Submissions: 8764   Accepted: 2576 ...

  2. [TyvjP1313] [NOIP2010初赛]烽火传递(单调队列 + DP)

    传送门 就是个单调队列+DP嘛. ——代码 #include <cstdio> ; , t = , ans = ~( << ); int q[MAXN], a[MAXN], f ...

  3. zstu 4237 马里奥的求救——(单调队列DP)

    题目链接:http://oj.acm.zstu.edu.cn/JudgeOnline/problem.php?id=4237 这题可以转化为每次可以走g~d+x步,求最大分数,且最大分数的步数最少. ...

  4. 1304F2 - Animal Observation (hard version) 线段树or单调队列 +DP

    1304F2 - Animal Observation (hard version) 线段树or单调队列 +DP 题意 用摄像机观察动物,有两个摄像机,一个可以放在奇数天,一个可以放在偶数天.摄像机在 ...

  5. 卖饲料——单调队列优化dp

    题目描述 约翰开车来到镇上,他要带K吨饲料回家.运送饲料是需要花钱的,如果他的车上有X吨饲料,每公里就要花费X^2元,开车D公里就需要D* X^2元.约翰可以从N家商店购买饲料,所有商店都在一个坐标轴 ...

  6. BZOJ1855 [Scoi2010]股票交易[单调队列dp]

    题 题面有点复杂,不概括了. 后面的状态有前面的最优解获得大致方向是dp.先是瞎想了个$f[i][j]$表示第$i$天手里有$j$张股票时最大收入(当天无所谓买不买). 然后写了一个$O(n^4)$状 ...

  7. 20152016-acmicpc-neerc-northern-subregional-contest J:Journey to the "The World's Start"(单调队列+DP+二分)

    http://codeforces.com/gym/100801/attachments 题意:给出n-1张不同的票,票价分别为 pi,每张票每次最多可以坐 r 个站(1<=r<n),并且 ...

  8. vijos P1243 生产产品(单调队列+DP)

      P1243生产产品   描述 在经过一段时间的经营后,dd_engi的OI商店不满足于从别的供货商那里购买产 品放上货架,而要开始自己生产产品了!产品的生产需要M个步骤,每一个步骤都可以在N台机器 ...

  9. POJ 1821 单调队列+dp

    题目大意:有K个工人,有n个墙,现在要给墙涂色.然后每个工人坐在Si上,他能刷的最大范围是Li,且必须是一个连续子区间,而且必须过Si,他刷完后能获得Pi钱 思路:定义dp[i][j]表示前i个人,涂 ...

随机推荐

  1. 四则运算----C++版

    一.设计思想 因java中已做过,就是简单的将java中的语句调换为C++的语句. 二.代码 #include<iostream.h> #include<Stdlib.h> v ...

  2. C程序第二次作业

    2-1删除字符串中数字字符 1.设计思路 (1)主要描述题目算法 第一步:遍历指针s所指的s数组. 第二步:如果 * (s+i)在0至9之间的话,则跳过此 * (s+i). 第三步:如果* (s+i) ...

  3. Linux进程间通信--信号量

    信号量绝对不同于信号,一定要分清,关于信号,上一篇博客中已经说过,如有疑问,请移驾! 信号量 一.是什么   信号量的本质是一种数据操作锁,它本身不具有数据交换的功能,而是通过控制其他的通信资源(文件 ...

  4. C++数据结构中的基本算法排序

    冒泡排序 基本思想:两两比较待排序的数,发现反序时交换,直到没有反序为止. public static void BubbleSort(int[] R) { for (int i = 0; i < ...

  5. KNN算法的代码实现

    # -*- coding: utf-8 -*-"""Created on Wed Mar 7 09:17:17 2018 @author: admin"&quo ...

  6. Oracle 使用pl/sql将表中的数据读出到文件中

    (1)在服务器上创建文件路径及文件 [oracle@redhat errormsg]$ touch test01.txt (2)在数据库中创建路径及授权 (3)创建存储过程 CREATE OR REP ...

  7. Hey,man,are you ok? -- 关于心跳、故障监测、lease机制

    电话之于短信.微信的一个很大的不同点在于,前者更加及时,有更快速直接的反馈:而后面两个虽然称之为instant message,但经常时发出去了就得等对方回复,等多久是不确定的.打电话能明确知道对方在 ...

  8. VS 2008 开发WinCE程序 编译部署速度慢的解决办法

    1.找到以下文件 C:\Windows\Microsoft.NET\Framework\v3.5\Microsoft.CompactFramework.Common.targets 2.用记事本打开该 ...

  9. PHP模式设计之单例模式、工厂模式、注册树模式、适配器模式、观察者模式

    php模式设计之单例模式 什么是单例模式? 单例模式是指在整个应用中只有一个实例对象的设计模式 为什么要用单例模式? php经常要链接数据库,如果在一个项目中频繁建立连接数据库,会造成服务器资源的很大 ...

  10. redis入门(14)redis集群下的数据分区存储

    redis入门(10)redis集群下的数据分区存储