n<=100,m<=1000的图,在此图上用油箱容量C<=1e5的车来旅行,旅行时,走一条边会耗一单伟油,在点i时,若油量<ci,则可以把油以pi的价格补到ci,pi<=n*n,ci<=1e5,现T<=1e5个询问:从Ai出发,带Yi<=n*n块钱走不少于Si<=1e9的路程,问最多剩多少钱。

方法一:其实就是问从某个点出发,走路程Si,问最少花费。F(i,j,k)--从i出发,剩下j的油,走路程k最小花费,决策一下在i要不要加油即可。

方法二:走路程Si问最小花费-->花费q问最长路程。F(i,j,q)--从i出发剩j的油,用q块钱最长路程,决策一下要不要在i加油即可。

方法三:整个路程其实就是由几个加油处为中转点拼起来的,因此只用加油处的状态就可以勾勒整个过程,而加油处加完油后,油箱状态和之前没关系,可以省掉。F(i,q)--从i出发用q块钱最长路程,F(i,q)=max(F(j,q-pi)+G(i,j)),G(i,j)表示从i开始,到j,经过不超过min(ci,C)条路的最长路。

G(i,j)的计算可以用倍增:W(i,j,k)表示i到j经过不超过2^k步的最长路程,用W来拼凑G。

最后询问时,在F(Ai)数组里二分找F(Ai,j)>=Si的最小的j,得答案。

有点复杂。。

 1 #include<stdio.h>
 2 #include<string.h>
 3 #include<stdlib.h>
 4 #include<math.h>
 5 #include<algorithm>
 6 //#include<iostream>
 7 using namespace std;
 8
 9 bool isdigit(char c) {return c>='0' && c<='9';}
10 int qread()
11 {
12     char c;int s=0,t=1;while (!isdigit(c=getchar())) (c=='-' && (t=-1));
13     do s=s*10+c-'0'; while (isdigit(c=getchar())); return s*t;
14 }
15 int n,m,C,T;
16 #define maxn 111
17 #define maxm 2017
18 struct Edge{int to,v,next;}edge[maxm];int first[maxn],le=2;
19 void in(int x,int y,int v) {Edge &e=edge[le];e.to=y;e.v=v;e.next=first[x];first[x]=le++;}
20
21 #define LL long long
22 LL f[maxn][maxn*maxn],g[maxn][maxn],tmp[maxn][maxn],w[maxn][maxn][22],c[maxn],p[maxn];
23 const LL inf=1e16;
24 void prebz()
25 {
26     for (int i=1;i<=n;i++)
27         for (int j=1;j<=n;j++)
28             w[i][j][0]=-inf;
29     for (int i=1;i<=n;i++)
30     {
31         w[i][i][0]=0;
32         for (int j=first[i];j;j=edge[j].next)
33         {
34             const Edge &e=edge[j];
35             w[i][e.to][0]=e.v;
36         }
37     }
38     for (int k=1;k<=18;k++)
39         for (int i=1;i<=n;i++)
40             for (int j=1;j<=n;j++)
41             {
42                 w[i][j][k]=-inf;
43                 for (int x=1;x<=n;x++)
44                     w[i][j][k]=max(w[i][j][k],w[i][x][k-1]+w[x][j][k-1]);
45             }
46     for (int i=1;i<=n;i++)
47     {
48         int o=min(c[i],1ll*C);
49         for (int j=1;j<=n;j++) g[i][j]=-inf;
50         g[i][i]=0;
51         for (int k=18;k>=0;k--) if (o&(1<<k))
52         {
53             for (int j=1;j<=n;j++) tmp[i][j]=-inf;
54             for (int j=1;j<=n;j++)
55                 for (int x=1;x<=n;x++)
56                     tmp[i][j]=max(tmp[i][j],g[i][x]+w[x][j][k]);
57             for (int j=1;j<=n;j++) g[i][j]=tmp[i][j];
58         }
59     }
60 }
61
62 void predp()
63 {
64     for (int j=0;j<=n*n;j++)
65         for (int i=1;i<=n;i++)
66         {
67             f[i][j]=0;
68             if (j>=p[i]) for (int x=1;x<=n;x++) f[i][j]=max(f[i][j],f[x][j-p[i]]+g[i][x]);
69         }
70 }
71
72 void init()
73 {
74     n=qread(),m=qread(),C=qread(),T=qread();
75     for (int i=1;i<=n;i++) p[i]=qread(),c[i]=qread();
76     for (int i=1,x,y,z;i<=m;i++)
77     {
78         x=qread(),y=qread(),z=qread();
79         in(x,y,z);
80     }
81 }
82
83 int main()
84 {
85     init();
86     prebz();
87     predp();
88     while (T--)
89     {
90         int x=qread(),y=qread(),z=qread();
91         int t=lower_bound(f[x]+1,f[x]+1+n*n,z)-f[x];
92         if (t<=y) printf("%d\n",y-t);
93         else puts("-1");
94     }
95     return 0;
96 }

View Code

转载于:https://www.cnblogs.com/Blue233333/p/7791577.html

LOJ#539. 「LibreOJ NOIP Round #1」旅游路线相关推荐

  1. 「LibreOJ NOIP Round #1」旅游路线

    「LibreOJ NOIP Round #1」旅游路线 题目链接 做法: 首先肯定要预处理些东西,来使单词询问达到\(o(logn)\)或者\(o(1)\)的复杂度,又因为距离这个东西的范围太大,我们 ...

  2. LOJ#538. 「LibreOJ NOIP Round #1」数列递推

    description sosusosu 虐爆 OI 之后成为了一名文化课选手.一天,他做作业碰到了一堆数列问题,每道题给出的数列都是以下形式: 给定一个下标从000开始,无限长的整数列ai{a_{i ...

  3. LOJ #510. 「LibreOJ NOI Round #1」北校门外的回忆(倍增+动态开点线段树)

    题目 这个题是一个精彩的分析性质区间离散的问题 真的详细 维护链真的一绝. LOJ\rm LOJLOJ最短ACCode\rm AC \ CodeAC Code #include<bits/std ...

  4. 【LibreOJ】#541. 「LibreOJ NOIP Round #1」七曜圣贤

    [题意]一开始车上有编号为0~a的红茶,过程中出现的红茶编号仅有[0,b),有三种操作: 1.买进编号未在车上出现过的红茶. 2.丢掉车上指定编号的红茶. 3.将最早丢出去的红茶捡回来. 每次操作后求 ...

  5. LOJ#510. 「LibreOJ NOI Round #1」北校门外的回忆(线段树)

    题面 传送门 题解 感谢\(@M\_sea\)的代码我总算看懂题解了-- 这个操作的本质就是每次把\(x\)的\(k\)进制最低位乘\(2\)并进位,根据基本同余芝士如果\(k\)是奇数那么最低位永远 ...

  6. LOJ #573. 「LibreOJ NOI Round #2」单枪匹马 线段树

    $f$ 函数暴力计算的话是 $O(n)$ 的(用一个 $\frac{x}{y}$ 来保存每一步计算结果,然后依次合并) 我们将一段区间的结果写成 $\frac{ax+by}{cx+dy}$ 的形式,初 ...

  7. LibreOJ NOIP Round #1」七曜圣贤

    B. 七曜圣贤 内存限制:1024 MiB时间限制:2500 ms标准输入输出 题目类型:传统评测方式:文本比较 题目描述 本题 C/C++ 时限 2.5 秒,Pascal 时限 5 秒.最后将改时限 ...

  8. 「LibreOJ NOI Round #2」不等关系 (dp+NTT分治)

    description 戳我看题目哦 solution 有一道非常相似的题目 一棵树,每条边限制两个端点的大小关系(限制 a[u]>a[v]a[u]>a[v]a[u]>a[v] 或 ...

  9. 【LOJ574】「LibreOJ NOI Round #2」黄金矿工

    [题目链接] 点击打开链接 [思路要点] 可参考 官方题解 . 以下为笔者个人的见解,方便起见,下称矿工为老鼠,金矿为洞. 我们可以对洞的权值加上深度,老鼠的权值减去深度,从而不需要考虑树的边权. 考 ...

最新文章

  1. windows性能计数器搜集方法
  2. SWTBOK測试实践系列(1) -- 測试在项眼下期的评审投入划算吗?
  3. 【推荐】揭秘谷歌电影票房预测模型
  4. leetcode刷题之树(2)
  5. 判断图有无环_判断无向图/有向图中是否存在环
  6. ---WebCam网络摄像头6 编译WebCam
  7. 如何禁用python警告
  8. 2017长春java平均工资_2016年长春在岗职工社会平均工资出炉:66948元,月平均工资5579元...
  9. 提升孩子的智力从用对方法做起
  10. comsol仿真模型:风力发电机复合材料叶片的应力和模态分析
  11. matlab符号运算转置出现conj的解决办法
  12. 规章制度的处理:既要照章处理,又要考虑特殊情况
  13. Android 12刷机教程
  14. python:实现abbreviation缩写算法(附完整源码)
  15. T51 运行文本指令
  16. 联想t450进入bios设置按哪个键_thinkpad笔记本怎么进bios设置|联想thinkpad开机进bios按哪个键-系统城...
  17. 视频号如何发表视频呢?
  18. 希望计算机专业都知道这些优质比赛
  19. 微信网页开发-长按二维码无法识别问题解决
  20. Excel基础—文件菜单之设置选项

热门文章

  1. 一款兼容双系统、为代码而生的机械键盘--Keychron K3
  2. Why I Love Kamailio?
  3. Scrum敏捷开发简介
  4. plupload附件上传下载+百度富文本编辑器
  5. fatal error C1859: 意外的预编译头错误,只需重新运行编译器就可能修复此问题
  6. 金蝶kis专业版公网访问_金蝶KIS客户端修改IP连接服务器的方法
  7. 中兴服务器管理口地址,跪求!!!怎么获取服务器管理口的IP地址???
  8. (整理)HTML字体标记:标题字体,字体大小,物理字体,逻辑字体,字体颜色,客户端字体,字符实体
  9. 微信小程序消息推送(订阅消息原模板消息)开发流程
  10. 免费的中医方剂管理软件