第十二章 贪心 7 AcWing 1517. 是否加满油

我不是女神ヾ 2024-03-31 13:55 186阅读 0赞

第十二章 贪心 7 AcWing 1517. 是否加满油

原题链接

AcWing 1517. 是否加满油

算法标签

贪心

思路

思路见代码

代码

  1. #pragma GCC optimize(2)
  2. #pragma GCC optimize(3)
  3. #include<bits/stdc++.h>
  4. #define int long long
  5. #define xx first
  6. #define yy second
  7. #define ump unordered_map
  8. #define us unordered_set
  9. #define pq priority_queue
  10. #define rep(i, a, b) for(int i=a;i<b;++i)
  11. #define Rep(i, a, b) for(int i=a;i>=b;--i)
  12. using namespace std;
  13. typedef pair<int, int> PII;
  14. const int N=505, inf=0x3f3f3f3f3f3f3f3f, mod=1e9+7;
  15. const double Exp=1e-8;
  16. //int t, n, m, cnt, ans;
  17. struct St{
  18. double p, d;
  19. bool operator<(const St &s){
  20. return d<s.d;
  21. }
  22. }s[N];
  23. inline int rd(){
  24. int s=0,w=1;
  25. char ch=getchar();
  26. while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
  27. while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar();
  28. return s*w;
  29. }
  30. void put(int x) {
  31. if(x<0) putchar('-'),x=-x;
  32. if(x>=10) put(x/10);
  33. putchar(x%10^48);
  34. }
  35. signed main(){
  36. ios::sync_with_stdio(false);
  37. cin.tie(0);
  38. cout.tie(0);
  39. // int cm=rd(), d=rd(), da=rd(), n=rd();
  40. int cm, d, da, n;
  41. scanf("%lld %lld %lld %lld", &cm, &d, &da, &n);
  42. rep(i, 0, n){
  43. scanf("%lf %lf", &s[i].p, &s[i].d);
  44. }
  45. s[n]={0, (double)d};
  46. sort(s, s+n+1);
  47. // 起点没有加油站
  48. if(s[0].d){
  49. printf("The maximum travel distance = 0.00");
  50. return 0;
  51. }
  52. // oil为当前油箱中的油 初始时还未决策 故油量为0
  53. double res=0, oil=0;
  54. for(int i=0; i<n; ){
  55. int k=-1;
  56. // 枚举当前油量能够走到的所有加油站 初始在0号点最远可达c_max * d_avg(油箱满)
  57. for(int j=i+1; j<=n&&s[j].d-s[i].d<=cm*da; ++j){
  58. // 找到第一个比起点价格小的
  59. if(s[j].p<s[i].p){
  60. k=j;
  61. break;
  62. }else if(k==-1||s[j].p<s[k].p){// 或者找一个不比起点小但比这一段最小的
  63. k=j;
  64. }
  65. }
  66. // 这一段之间没有加油站
  67. if(k==-1){
  68. printf("The maximum travel distance = %.2lf", s[i].d+(double)cm*da);
  69. return 0;
  70. }
  71. // 存在比当前加油站更便宜的加油站A 只补充合适的油
  72. if(s[k].p<=s[i].p){
  73. // (s[k].d-s[i].d)/da
  74. // 走到A站的总耗油量
  75. // (s[k].d-s[i].d)/da-oil
  76. // 总耗油量减去当前油箱中的油量为需要补充的油量
  77. // ((s[k].d-s[i].d)/da-oil)*s[i].p
  78. // 需要补充的油量的花费
  79. res+=((s[k].d-s[i].d)/da-oil)*s[i].p;
  80. // 此时剩余的油量只能够正好走到下一站
  81. i=k;
  82. // 走到下一站后油量刚好耗尽
  83. oil=0;
  84. }else{ /* 可达范围内存在加油站 但价格都比当前加油站的价格更高
  85. 此时最优选择是在当前车站把油箱填满 到了范围内最低价格的加油站再做下一步选择*/
  86. // 花费为: 走到[花费最优的加油站]的距离 * 油价
  87. res+=(cm-oil)*s[i].p;
  88. // 走到那里时油量为:满油减去耗费的油
  89. oil=cm-(s[k].d-s[i].d)/da;
  90. i=k;
  91. }
  92. }
  93. printf("%.2lf", res);
  94. return 0;
  95. }

参考文献

AcWing 1517. 是否加满油(PAT甲级辅导课)y总视频讲解
AcWing 1517. 是否加满油—注释版

原创不易
转载请标明出处
如果对你有所帮助 别忘啦点赞支持哈
在这里插入图片描述

发表评论

表情:
评论列表 (有 0 条评论,186人围观)

还没有评论,来说两句吧...

相关阅读