GYM 100801J Journey to the “The World's Start”

Problem J. Journey to the “TheWorld’s Start”

Input file:

journey.in

Output file:

journey.out

Time limit:

2 seconds

Memory limit:

256 megabytes

Jerry Prince is the fourth grade studentand he goes to New-Lodnon to visit the most popular amusement park “The World’sStart”.

An airport he arrives at is next to thefirst stop of the metro line. This line hasnstops and “The World’s Start” is on the last of them. The metro ofNew-Lodnon is pretty fast so you may assume that you can get from a stop to thenext one in just one minute.

Jerry needs a travel card to use the metro. Each travel card has arange r and a price p. With a travel card of range r Jerry may travel no more thanr stops at once. Therefore, if Jerryenters metro at the stop i he shouldexit on one of the stops from i r to i+ r inclusive. It takes di minutes to exit andreenter metro ati-th stop. There isno time required to enter the first stop or exit the last one.

Jerry is not very rich but he has some spare time, so he decided tobuy the cheapest travel card that will allow him to travel from the first metrostop to the last one in no more thant minutes.Input

The first line of the input file containstwo integers n and t — the number of stops and the maximumpossible time (2 ≤ n ≤ 50000; n− 1 ≤ t ≤ 109).

The second line contains n − 1 integers pr — the prices of travel cards with ranger = 1...n− 1 (1 ≤ pr ≤ 100000)

The third line contains n −2 integers di — the numberof minutes required to reenter metro at stopi = 2...n − 1 (1 ≤ di ≤ 105). Output

Output a single integer p — the lowest possible price of onetravel card that allows Jerry to travel from the first to the last stop in nomore thant minutes.

Example

journey.in

 

journey.out

4 4

1 2 3

1 4

2

 


这好像是我碰到的第一道不太好描述题意的题目=。=


第一行输入两个数据 n, m。表示你去一个城市坐地铁,有n个地铁站,线性排布,要求你在m时间内从 1 坐到 n 。


接下来是 n - 1 个数字ma_i。表示第 i 种车票需要 ma_i 元


当你手持第 i 种车票的时候,你一次性最多可以坐 i 站。即加入你现在在 x 号站台,你可以一次性用 i 种车票到达 [x - i, x + i] 区间内的任意站台。


只能选择一种车票,可多次使用同一种车票。


再接下来是 n - 2 个数字,第 i 个数字表示加入你在i + 1 号站台下车需要额外花费多少时间,1 号和 n 号下车不需要花费时间。


从一站坐地铁到下一站需要花费 1 时间。


问在 m 时间内,你花费最少的钱能从 1 到达 n,输出钱数。


样例:

4 4

1 2 3

1 4

你选择第二种车票,先在二号站下车,再直达重点。 花费时间为 1 + 3

如果选择第一种车票,你必须在二号,三号都下车,花费时间 1 + 4 + 3




显然可以想到的就是我们没必要倒着坐车,所以我们路上必须花的时间为 n - 1。

然后贪心票价,当一个地铁票 a 可达范围小于地铁票 b 且价格高于地铁票b,那么地铁票 a 可以直接舍去。

这样我们就构造出了一个单调序列。


然后考虑对这个单调序列二分票价,然后DP



dp[i] 表示用 到达范围 为 range 的票到第 i 站花费的最少钱数。

dp[n] <= m - n + 1时返回 true


状态转移方程  dp[i] = min(dp[i - j]) + cost[i]  (1 <= i <= n, 1 <= j <= min(i - 1, range) )


如果直接算,时间复杂度是O(log * n * n)


于是我们需要快速求一个区间的最小值


用线段树或者分块优化快速求 min(dp[i - j])

这样我们就把一个n 变成了log 或者 sqrt(n)

线段树现场写 A 了,不懂分块会不会被 T。


然后好像有学长用最短路过了??

一脸懵逼

  1. #include <bits/stdc++.h>  
  2. #define pb push_back  
  3. #define mp make_pair  
  4. #define LL long long  
  5. using namespace std;  
  6.   
  7. const int N = 100010;  
  8. const int INF = 0x3f3f3f3f;  
  9.   
  10. struct Tree  
  11. {  
  12.     int l;  
  13.     int r;  
  14.     int minn;  
  15. };  
  16.   
  17. struct Stack  
  18. {  
  19.     int r;  
  20.     int p;  
  21. };  
  22.   
  23. Tree tree[N * 4];  
  24. Stack st[N];  
  25. LL dp[N];  
  26. int cost[N];  
  27. int ans;  
  28. int len;  
  29. int n, m;  
  30. int w;  
  31. int li;  
  32.   
  33. void up(int x)  
  34. {  
  35.     tree[x].minn = min(tree[x << 1].minn, tree[x <<1 | 1].minn);  
  36. }  
  37.   
  38. void build(int x, int l, int r)  
  39. {  
  40.     tree[x].l = l;  
  41.     tree[x].r = r;  
  42.     tree[x].minn = INF;  
  43.     if(l == r){  
  44.         tree[x].minn = dp[l];  
  45.     }  
  46.     else{  
  47.         int mid = l + ((r - l) >> 1);  
  48.   
  49.         build(x << 1, l, mid);  
  50.         build(x << 1 | 1, mid + 1, r);  
  51.         up(x);  
  52.     }  
  53. }  
  54.   
  55. void update(int x, int p, int v)  
  56. {  
  57.     int ll = tree[x].l;  
  58.     int rr = tree[x].r;  
  59.   
  60.     if(ll == p && rr == p){  
  61.         tree[x].minn = v;  
  62.         dp[ll] = v;  
  63.     }  
  64.     else{  
  65.         int mid = ll + ((rr - ll) >> 1);  
  66.   
  67.         if(p <= mid){  
  68.             update(x << 1, p, v);  
  69.         }  
  70.         else{  
  71.             update(x << 1 | 1, p, v);  
  72.         }  
  73.         up(x);  
  74.     }  
  75. }  
  76.   
  77.   
  78. void query(int x, int l, int r)  
  79. {  
  80.     int ll = tree[x].l;  
  81.     int rr = tree[x].r;  
  82.   
  83.     if(ll == l && rr == r){  
  84.         if(tree[x].minn < ans){  
  85.             ans = tree[x].minn;  
  86.         }  
  87.   
  88.         ans = min(ans, tree[x].minn);  
  89.         return;  
  90.     }  
  91.     else{  
  92.         int ans = INF;  
  93.         int mid = ll + ((rr - ll) >> 1);  
  94.   
  95.         if(l <= mid){  
  96.             query(x << 1, l, min(r, mid));  
  97.         }  
  98.         if(r > mid){  
  99.             query(x << 1 | 1, max(mid + 1, l), r);  
  100.         }  
  101.         up(x);  
  102.     }  
  103. }  
  104.   
  105. bool check(int mid)  
  106. {  
  107.     memset(dp, 0, sizeof(dp));  
  108.     dp[1] = 0;  
  109.     build(1, 1, n);  
  110.     for(int i = 2; i <= n; i ++){  
  111.         ans = INF;  
  112.         query(1, max(1, i - mid), i - 1);///查询  
  113.         update(1, i, ans + cost[i]);///更新 dp  
  114.     }  
  115.     if(dp[n] > li){///li = m - n + 1;  
  116.         return false;  
  117.     }  
  118.     else{  
  119.         return true;  
  120.     }  
  121. }  
  122.   
  123. int main()  
  124. {  
  125.     int l, r;  
  126.     int right;  
  127.   
  128.     while(scanf("%d%d", &n, &m) == 2){  
  129.         len = 0;  
  130.         li = m - n + 1;  
  131.         memset(cost, 0, sizeof(cost));  
  132.   
  133.         scanf("%d", &w);  
  134.         st[len].r = 1;  
  135.         st[len].p = w;  
  136.         len ++;  
  137.         for(int i = 2; i < n; i ++){  
  138.             scanf("%d", &w);  
  139.             while(w <= st[len - 1].p && len){///构造单调序列  
  140.                 len --;  
  141.             }  
  142.             st[len].r = i;  
  143.             st[len].p = w;  
  144.             len ++;  
  145.         }  
  146.         for(int i = 2; i < n; i ++){  
  147.             scanf("%d", &cost[i]);  
  148.         }  
  149.         l = 1;  
  150.         r = len;  
  151.         while(l <= r){  
  152.             int mid = l + ((r - l) >> 1);  
  153.             int t = st[mid - 1].r;  
  154.   
  155.             if(check(t)){  
  156.                 r = mid - 1;  
  157.             }  
  158.             else{  
  159.                 l = mid + 1;  
  160.             }  
  161.         }  
  162.   
  163.         printf("%d\n", st[l - 1].p);  
  164.     }  
  165.   
  166.     return 0;  

回答: 当出现"ERROR: Could not find a version that satisfies the requirement gym"错误时,这通常是因为pip无法找到与所需包(gym)匹配的版本。\[1\]这可能是由于以下几个原因导致的:一、所需包(gym)的版本不可用;二、pip源配置不正确;三、网络连接问题。为了解决这个问题,你可以尝试以下几种解决办法:一、确保你使用的是正确的包名称和版本号,可以在官方文档或其他可靠来源中查找正确的包名称和版本号;二、检查你的pip源配置,确保它指向正确的源;三、检查你的网络连接,确保你可以正常访问互联网。如果以上方法都没有解决问题,你可以尝试使用其他安装包的方法,比如使用conda进行安装。\[2\] #### 引用[.reference_title] - *1* *2* [Python pip install 安装包报错ERROR: Could not find a version that satisfies the requirement XXX解决...](https://blog.csdn.net/ArsenLupin/article/details/128212836)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [实验室linux服务器安装gym出现的问题](https://blog.csdn.net/xiaochen_hzau/article/details/127220463)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值