usaco 购买饲料 && 修剪草坪
购买饲料
Description
如约翰在镇上,沿着公路开车回家,他的家离起点有E公里。他顺便准备买K吨饲料回家。运送饲料是要花油钱的,如果他的车上有X吨饲料,行驶一公里需要X^2元,行驶D公里就 需要DX^2元。约翰可以从N家商店购买饲料,所有商店都在公路边上,第i家店距离起点Xi公里,饲料单价为每吨Ci元,库存为Fi吨。
约翰可以选择在任意商店里购买任意多的饲料,只要那家店的还有货就可以了。保证所有商店的饲料库存之和不会少于K,为了带K吨饲料回家,约翰最少的花费是多少呢?
举个例子,假设有三家商店,情况如下所示:
坐标 X = 1 X = 3 X = 4 E = 5
库存 1 1 1
单价 1 2 2
如果约翰要买2吨饲料回家,那么他的最好选择是在离家较近的两家商店购买饲料,则花在路上的钱是1 + 4 = 5,花在商店的钱是2 + 2 = 4,共需要9元。
Input Format
第一行:三个用空格分开的整数:K,E和N,1 ≤ K ≤ 10000,1 ≤ E,N ≤ 500
第二行到N + 1行:第i + 1行有三个用空格分开的整数一个整数: Xi, Fi和Ci, 0 < Xi < E, 1 ≤ Fi ≤ 10000,1 ≤ Ci ≤ 10,000,000
Output Format
第一行:单个整数,表示约翰购买和运送饲料的最小花费
--------------------------------------------------------------
正解=动归+队列优化
先考虑无优化的Dp
状态:f[i][j] 表示 在 i 这个位置且车上有 j 吨饲料至少要多少钱
转移: f[i+1][j]=f[i][j-g]+C[i]*g+j*j*( X[i+1]-X[i] )( 0<=g<=F[i] )
输出:f[n+1][k](设n+1为家)
显然O(N*K*F)必然会TLE
考虑优化
设 g‘=j-g 则 j-g’=g( 0<=g<=F[i] ),
g 增加 ,g‘ 减少,
则上面的 f[i+1][j] 可表示成
f[i+1][j]=f[i][ g’ ]+C[i]*( j-g' )+j*j*( X[i+1]-X[i])
=f[i][ g’ ]+ C[i]*j - C[i]*g' +j*j*( X[i+1]-X[i] )
( j-F[i] <= g' <=j ) (g' 必然小于 j,无需处理)
显然 C[i]*j 和 j*j*( X[i+1]-X[i] ) 为定值,
f[i+1][j]的值由 f[i][ g’ ] - C[i]* g' 决定,
可构造队列q(元素为 g‘ ):
从 0 到 f[i]一一进队(j)
如果 j-q.front()>F[i] 出队
j 进队,保持队列递减
f[i+1][j]=f[i][q[head] ]+ C[i]*( j-q[head] ) - C[i]*g' +j*j*( X[i+1]-X[i] )
复杂度O(N*K)不会 T 了- =(Orz Ak God)
代码如下:
#include<cstring>
#include<algorithm>
#include<cstdio>
#include<string>
#include<iostream>
#include<queue>
#define LL long long
#define INF 99999999999LL
struct Cow{
int x,tot,c;
}a[];
bool cmp(const Cow&X,const Cow&Y){
return X.x<Y.x;
}
int K,E,n,head,tail;
long long f[][];
int q[];
int main(){
scanf("%d%d%d",&K,&E,&n);
for(int i=;i<=K;i++) f[][i]=INF;
f[][]=;
for(int i=;i<=n;i++) scanf("%d%d%d",&a[i].x,&a[i].tot,&a[i].c);
std :: sort(a+,a+n+,cmp);
a[n+].x=E;
for(int i=;i<=n;i++){
head= ;
tail=;
LL tot=a[i].tot,c=a[i].c;
for(int j=,k;j<=K;j++){
while(head<=tail&&j - q[head] > tot ) ++head;
while(head<=tail&&f[i][j]-j * c<f[i][q[tail]]-q[tail] * c) --tail ;
q[++tail]=j;
k=j-q[head];
f[i+][j]=f[i][j-k]+k*c+1LL*j*j*(a[i+].x-a[i].x);
}
}
printf("%lld",f[n+][K]);
}
----------------------------------------------------------------
修剪草坪
Description
在去年赢得了小镇的最佳草坪比赛后,约翰变得懒惰了,再也没有修剪过草坪了。现在,新一轮的比赛又开始了,约翰希望能够再次夺冠。然而,约翰的草坪非常脏乱,因此,约翰需要让他的奶牛来完成这项工作。约翰有N头奶牛,平时排成一条直线,编号为1到N。每只奶牛的能力是不同的,第i头奶牛的能力为Ei。靠在一起的奶牛很熟悉,所以如果安排编号连续的K + 1头奶牛在一起工作,她们就会密谋罢工。因此,约翰需要你的帮助。如何挑选奶牛,才能使她们的工作能力之和最高,而且不会罢工呢?
Input Format
第一行:两个用空格隔开的整数:N和K,1 ≤ N ≤ 105,1 ≤ K ≤ N
第二行到N + 1行:第i + 1行有一个整数,表示第i头牛的能力Ei,1 ≤ Ei ≤ 109
Output Format
第一行:单个整数,表示最大的工作能力之和
----------------------------------------------------------------------------
和上题一样想考虑裸Dp
预处理: sum[i] 表示从第一头奶牛到第 i 头奶牛的能力和,
状态: f[i]表示到到第i头可得到的最大能力值和,
转移: f[i]=f[j]+sum[i]-sum[j+1]
比上一题简单,很容易看出sum[i]是个定值,
按 f[j]-sum[j+1] 做单调队列即可,
Ps.注意 k=1 时的情况
代码如下:
#include<cstring>
#include<algorithm>
#include<cstdio>
#include<string>
#include<iostream>
#include<queue>
#define INF 99999999
#define Max(x,y) if(y>x) x=y
#define ll long long
using namespace std;
ll head,tail,q[],p[],f[],n,k,sum[],ans;
int main(){
scanf("%lld%lld",&n,&k);
for(int i=;i<=n;i++){
scanf("%d",&sum[i]);
sum[i]+=sum[i-];
q[i]=-INF;
}
head=;
tail=;
for(ll i=;i<=k;i++) {
f[i]=sum[i];
while(f[i]-sum[i+]>=q[tail]&&tail>=head) --tail;
q[++tail]=f[i]-sum[i+];
p[tail]=i;
ans=max(f[i],ans);
}
for(ll i=k+;i<=n;i++){
while(i-p[head]->k) ++head;
f[i]=max(f[i-]+sum[i]-sum[i-],q[head]+sum[i]);
while(f[i]-sum[i+]>=q[tail]&&tail>=head) --tail;
q[++tail]=f[i]-sum[i+];
p[tail]=i;
ans=max(f[i],ans);
}
printf("%lld",ans);
}
usaco 购买饲料 && 修剪草坪的更多相关文章
- BZOJ2442: [Usaco2011 Open]修剪草坪
2442: [Usaco2011 Open]修剪草坪 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 500 Solved: 244[Submit][ ...
- BZOJ 2442: [Usaco2011 Open]修剪草坪( dp )
dp dp[ i ] 表示第 i 个不选 , 前 i 个的选择合法的最小损失 , dp[ i ] = min( dp[ j ] ) ( max( 0 , i - 1 - k ) <= j < ...
- bzoj2442[Usaco2011 Open]修剪草坪 单调队列优化dp
2442: [Usaco2011 Open]修剪草坪 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 1159 Solved: 593[Submit] ...
- BZOJ_2343_[Usaco2011 Open]修剪草坪 _单调队列_DP
BZOJ_2343_[Usaco2011 Open]修剪草坪 _单调队列_DP 题意: N头牛,每头牛有一个权值,选择一些牛,要求连续的不能超过k个,求选择牛的权值和最大值 分析: 先考虑暴力DP,f ...
- 【BZOJ2059】Buying Feed 购买饲料
题面 约翰开车来到镇上,他要带V吨饲料回家.如果他的车上有X吨饲料,每公里就要花费X^2元,开车D公里就需要D* X^2元.约翰可以从N家商店购买饲料,所有商店都在一个坐标轴上,第i家店的位置是Xi, ...
- P2627 修剪草坪
P2627 修剪草坪 题目描述 在一年前赢得了小镇的最佳草坪比赛后,Farm John变得很懒,再也没有修剪过草坪.现在,新一轮的最佳草坪比赛又开始了,Farm John希望能够再次夺冠. 然而,Fa ...
- [BZOJ2442][Usaco2011 Open]修剪草坪 dp+单调队列优化
2442: [Usaco2011 Open]修剪草坪 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 1118 Solved: 569[Submit] ...
- 洛谷 P2616 [USACO10JAN]购买饲料II Buying Feed, II
洛谷 P2616 [USACO10JAN]购买饲料II Buying Feed, II https://www.luogu.org/problemnew/show/P2616 题目描述 Farmer ...
- [USACO10NOV]购买饲料Buying Feed 单调队列优化DP
题目描述 约翰开车来到镇上,他要带 KKK 吨饲料回家.运送饲料是需要花钱的,如果他的车上有 XXX 吨饲料,每公里就要花费 X2X^2X2 元,开车D公里就需要 D×X2D\times X^2D×X ...
随机推荐
- a标签使用
1.发起邮件 注意:如果mailto后面同时有多个参数的话,第一个参数必须以“?”开头,后面的参数每一个都以“&”分隔. <a href="mailto:281345774@q ...
- Java调用.Net WebService参数为空解决办法 (远程)调试webservice方法 转
Java调用.Net WebService参数为空解决办法 (远程)调试webservice方法 同事遇到一个很囧的问题,java调,netwebservice的时候,调用无参数方法成功,调用有参 ...
- Windows加密视频播放器使用教程
1. 下载文件 http://pan.baidu.com/s/1c2aESQs 2. 操作流程 温馨提示 播放时,请务必保证播放设备联网(原因:用户名权限验证需要网络,播放后10秒即可关闭网 ...
- java 文件类操作(转载)
11.3 I/O类使用 由于在IO操作中,需要使用的数据源有很多,作为一个IO技术的初学者,从读写文件开始学习IO技术是一个比较好的选择.因为文件是一种常见的数据源,而且读写文件也是程序员进行IO编程 ...
- STM32学习内容和计划
一.STM32学习内容(流程) 1.学习STM32开发流程 ①MDK使用.建立工程.调试等 ②库开发方法 2.学习STM32常用外设开发 ①GPIO ②中断 ③定时器 ④串口 ⑤CAN 3.学习STM ...
- JavaScript高级之闭包的概念及其应用
主要内容: 什么是闭包 闭包使用的一般模式 闭包都能做些什么 本文是我的JavaScript高级这个系列中的第二篇文章. 在这个系列中,我计划分析说明 一下JavaScript中的一些常用的而又神秘的 ...
- Solr4.8.0源码分析(27)之ImplicitDocRouter和CompositeIdRouter
同样在公司工作中发现了一个现象, 1.我用/solr/admin/collections?action=CREATE&name=collection&numShards=3&r ...
- XE5 开发android平台搭建
转载自:http://www.cnblogs.com/hezihang/p/3319980.html Delphi XE5的Android开发平台搭建 Delphi XE5支持Android AR ...
- Word中表格内容被遮挡
RT,输入内容后下面的主任签字会被遮挡,解决办法:选中整个表格右键,表格属性,行高值设置为最小值,然后设置允许跨页断行:有人说右键按内容调整表格也行,没试过............
- 使用 Cloud Insight SDK 监控北京空气质量!
现在越来越多的 App 都开始有广告了.特别是空气质量监测,和天气类的 App,广告还是蛮多的,眼花缭乱,真是够了. 最近刚好在用一款系统监控工具 Cloud Insight,它提供的 SDK 可以把 ...