洛谷 P2317 [HNOI2005]星际贸易 解题报告
P2317 [HNOI2005]星际贸易
题目描述
输入输出格式
输入格式:
输出格式:
如果可以找到这样的方案,那么输出文件output.txt中包含两个整数X和Y。X表示贸易额,Y表示净利润并且两个数字之间用一个空格隔开。如果不能完成这次星际贸易,那么输出文件output.txt中包含 “Poor Coke!”(不包括引号)。
不知道为什么网上找不到txt的,于是只好copy了洛谷的,侵删。
首先理清一下题目。
这老哥的第一目的是想让自己卖的钱最多,第二目的是在卖的钱最多的基础上把利润搞大一点。
很容易发现,第一目的就是个普通的01背包,而且题目说了有唯一解。
用\(is[i][j]\)存储第\(i\)个星球\(j\)状态时是否由在\(i\)上卖东西得到的,得到必须去的星球。
第二目的就比较坑了,经过仔细的读题,我们发现这个维护是个捆绑销售啊,你只要上去星球了,你就必须得维护。
虽说这样比较无良,但不可置否的,也给我们做题带来了方便啊,我们可以对维护少一些决策。
我们看看这个燃料,虽然他能带的上看起来很多,但实际上也只需要最多4000就够了,我们试试对燃料做个背包。
\(dp[i][j]\)代表在第\(i\)个星球正准备出发(出发的加速还未使用)时,拥有\(j\)燃料的花费最小值。
\(dp[i][j]=min(dp[i][j],dp[k][j+2+cnt]+cnt*p[i]+f[i]),i>k,l[i]-l[k]>=l0\)
转移方程如上,要枚举$i,j,k,cnt$4维,绝对爆了
怎么优化?
对完全背包熟悉的话,也许比较容易就可以优化到\(O(N^3)\)
即\(dp[i][j]=min(dp[i][j-1]+p[i],dp[k][j+2]+f[i]),i>k,l[i]-l[k]>=l0\)
对\(k\)这一维怎么办呢?
我们发现,对于每一次使用,我们其实都找了很多遍\(dp[k][j+2]\)的最小值。
我们为什么不能把之前找到给利用起来呢?
好了,单调队列维护一下。
至此,复杂度就降到了\(O(N^2)\)
code:
#include <cstdio>
#include <cstring>
int min(int x,int y) {return x<y?x:y;}
const int N=2002;
const int inf=0x3f3f3f3f;
int dp[N][(N<<1)+10];
int n,m,r,l0;//点,货物,燃料,距离
int a[N],b[N],l[N],p[N],f[N];//量,钱,距,燃,维修
//此时dp[i][j]代表前i个星球卖j货物时的最大值
int is[N][N];//是否在i星球j状态卖东西
int is_s[N],m_max,m_min;
void s_dp()
{
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
{
dp[i][j]=dp[i-1][j];
if(j>=a[i]&&dp[i][j]<dp[i-1][j-a[i]]+b[i])
{
dp[i][j]=dp[i-1][j-a[i]]+b[i];
is[i][j]=1;
}
}
int j;
for(int i=0;i<=m;i++)
if(dp[n][i]>m_max)
{
m_max=dp[n][i];
j=i;
}
for(int i=n;i>0;i--)
{
if(is[i][j])
{
j-=a[i];
is_s[i]=1;
}
}
is_s[n]=1;
}
//此时dp[i][j]代表前i个星球装j燃料时正准备出发的费用
int q[(N<<1)+5][N][2],L[N],R[N];//0首1尾
void push(int j,int c,int id){q[j][++R[j]][0]=c;q[j][R[j]][1]=id;}
void front_pop(int j){R[j]--;}
void back_pop(int j){L[j]++;}
bool is_empty(int j) {return L[j]==R[j];}
void p_dp()
{
memset(dp,0x3f,sizeof(dp));
m=min(N,r);
dp[0][m]=0;
push(m,0,0);
for(int i=1;i<=n;i++)
for(int j=0;j<=m;j++)
{
while(!is_empty(j+2)&&l[i]-l[q[j+2][L[j+2]+1][1]]>l0)
back_pop(j+2);//超出距离
int id1=q[j+2][L[j+2]+1][1];//停的可行性最小值坐标
dp[i][j]=min(dp[id1][j+2]+f[i],dp[i][j]);//从前面停
if(p[i]&&j)
dp[i][j]=min(dp[i][j],dp[i][j-1]+p[i]);//或者买油
if(is_s[i])
L[j]=R[j]=0;
while(!is_empty(j)&&dp[i][j]<=q[j][R[j]][0]) front_pop(j);//更新单队
push(j,dp[i][j],i);
}
m_min=inf;
for(int i=0;i<=m;i++)
m_min=min(dp[n][i],m_min);
}
int main()
{
scanf("%d%d%d%d",&n,&m,&r,&l0);
for(int i=1;i<=n;i++)
scanf("%d%d%d%d%d",a+i,b+i,l+i,p+i,f+i);
for(int i=1;i<=n;i++)
if(l[i]-l[i-1]>l0)
{
printf("Poor Coke!\n");
return 0;
}
s_dp();
p_dp();
if(m_min<inf)
printf("%d %d\n",m_max,m_max-m_min);
else
printf("Poor Coke!\n");
return 0;
}
事实上要注意几个细节:
- 到第一问求得星球上时要清空单队(以前的情况失效了)
- 判能不能到不是看他亏不亏。
- 写的巧一点可以不用先判一次无解(有的状态拿0转移了)
2018.5.26
洛谷 P2317 [HNOI2005]星际贸易 解题报告的更多相关文章
- 洛谷 P1073 最优贸易 解题报告
P1073 最优贸易 题目描述 \(C\)国有\(n\)个大城市和\(m\)条道路,每条道路连接这\(n\)个城市中的某两个城市.任意两个城市之间最多只有一条道路直接相连.这\(m\)条道路中有一部分 ...
- 洛谷 P2469 [SDOI2010]星际竞速 解题报告
题目描述 10年一度的银河系赛车大赛又要开始了.作为全银河最盛大的活动之一,夺得这个项目的冠军无疑是很多人的梦想,来自杰森座α星的悠悠也是其中之一. 赛车大赛的赛场由N颗行星和M条双向星际航路构成,其 ...
- 洛谷_Cx的故事_解题报告_第四题70
1.并查集求最小生成树 Code: #include <stdio.h> #include <stdlib.h> struct node { long x,y,c; ...
- 洛谷 P3802 小魔女帕琪 解题报告
P3802 小魔女帕琪 题目背景 从前有一个聪明的小魔女帕琪,兴趣是狩猎吸血鬼. 帕琪能熟练使用七种属性(金.木.水.火.土.日.月)的魔法,除了能使用这么多种属性魔法外,她还能将两种以上属性组合,从 ...
- 洛谷 P2606 [ZJOI2010]排列计数 解题报告
P2606 [ZJOI2010]排列计数 题目描述 称一个\(1,2,...,N\)的排列\(P_1,P_2...,P_n\)是\(Magic\)的,当且仅当对所以的\(2<=i<=N\) ...
- 洛谷1303 A*B Problem 解题报告
洛谷1303 A*B Problem 本题地址:http://www.luogu.org/problem/show?pid=1303 题目描述 求两数的积. 输入输出格式 输入格式: 两个数 输出格式 ...
- 洛谷 P2542 [AHOI2005]航线规划 解题报告
P2542 [AHOI2005]航线规划 题目描述 对Samuel星球的探险已经取得了非常巨大的成就,于是科学家们将目光投向了Samuel星球所在的星系--一个巨大的由千百万星球构成的Samuel星系 ...
- 洛谷 P3084 [USACO13OPEN]照片Photo 解题报告
[USACO13OPEN]照片Photo 题目描述 农夫约翰决定给站在一条线上的\(N(1 \le N \le 200,000)\)头奶牛制作一张全家福照片,\(N\)头奶牛编号\(1\)到\(N\) ...
- 洛谷 P1379 八数码难题 解题报告
P1379 八数码难题 题目描述 在3×3的棋盘上,摆有八个棋子,每个棋子上标有1至8的某一数字.棋盘中留有一个空格,空格用0来表示.空格周围的棋子可以移到空格中.要求解的问题是:给出一种初始布局(初 ...
随机推荐
- [转]Web 通信 之 长连接、长轮询(long polling)
本篇文章转载自Web 通信之长连接.长轮询(longpolling),版权归作者所有. 转者按:随着技术的发展,在HTML5中,可以通过WebSocket技术来完成长连接的开发,虽然如此,本文依然存在 ...
- [Oracle]为何Archivelog 没有马上被删除
[Oracle]为何Archivelog 没有马上被删除 客户设置了 Archivelog 的 deletion policy 是 CONFIGURE ARCHIVELOG DELETION POLI ...
- CentOS 7 安装Redis
Linux安装Redis 一.下载并安装 $ wget http://download.redis.io/releases/redis-2.8.17.tar.gz $ tar xzf redis-2. ...
- 百度之星-day2-1004-二分答案
由于序列有序,求其中一个最优解,二分答案即可,注意二分时上边界满足才保存 #include<iostream> #include<stdio.h> #include<st ...
- 5 questions
1.软件开发中有哪几种过程模型? 2.详细设计有哪几种描述方法? 3.什么是需求分析? 4.软件设计的基本原理包括哪些内容? 5.简述文档在软件工程中的作用? 逸翔.
- 软件工程M1/M2总结及阅读作业总结
一.软件工程M1/M2总结 写下这篇总结的时候,我们的软件项目尚未完工.虽然尝试申请了延期答辩,但最终未能成功.这意味着,我们的项目能否正常发布已经处于了一个微妙的状态.可能可以,也可能不可以.只能尽 ...
- linux第四次读书笔记
第四章:进程调度 一.多任务 1.非抢占式多任务 进程会一直执行直到自己主动停止运行(这一步骤称为让步) 2.抢占式多任务 Linux/Unix使用的是抢占式的方式:强制的挂起进程的动作就叫做抢占.进 ...
- sql 语句的先后执行顺序
例:查询语句中select from where group by having order by的执行顺序 一般以为会按照逻辑思维执行,为: 查询中用到的关键词主要包含六个,并且他们的顺序依次为 ...
- 软件工程个人项目作业 Individual Project
利用Junit4进行程序模块的测试,回归测试 源码 https://github.com/dpch16303/test/blob/master/%E5%9B%9E%E5%BD%92%E6%B5%8B% ...
- Oracle系列(一): Oracle数据恢复
Oracle数据恢复 在使用Oracle的时候,突然一部小心update或者delete全部数据后怎么办? select * from table as of timestamp to_timest ...