1. 程式人生 > >洛谷 P4266 [USACO18FEB] Rest Stops

洛谷 P4266 [USACO18FEB] Rest Stops

題意翻譯

Farmer John和他的私人教練Bessie正在徒步攀登溫哥牛山。基於他們的目的(也是你的目的),這座山可以用一條長為LLL米(1≤L≤1061 \leq L \leq 10^61≤L≤106)的長直路徑表示。Farmer John會沿著這條路徑以每米rFr_FrF​秒(1≤rF≤1061 \leq r_F \leq 10^61≤rF​≤106)的固定速度攀登。由於他正在訓練他的耐力,他在途中不會進行任何的休息。 然而Bessie可以在休息站休息,在那裡她能夠找到一些美味的嫩草。當然,她也不能在任何地方都休息!在路徑上總共有NNN個休息站(1≤N≤1051 \leq N \leq 10^51≤N≤105);第iii個休息站距離路徑的起點xix_ixi​米(0<xi<L0 < x_i < L0<xi​<L),美味值為cic_ici​(1≤ci≤1061 \leq c_i \leq 10^61≤ci​≤106)。如果Bessie在休息站iii休息了ttt秒,她能夠得到ci⋅tc_i \cdot tci​⋅t個美味單位。

不在休息站的時候,Bessie會以每米rBr_BrB​秒(1≤rB≤1061 \leq r_B \leq 10^61≤rB​≤106)的固定速度攀登。由於Bessie年輕而健康,rBr_BrB​嚴格小於rFr_FrF​。

Bessie想要吃到最多的美味嫩草。然而她也擔心Farmer John;她認為如果在任何時候她位於Farmer John身後,Farmer John可能就會失去前進的動力了!

幫助Bessie求出,在確保Farmer John能夠完成登山的情況下,她能夠獲得的最多的美味單位。

輸入格式(檔名:reststops.in): 輸入的第一行包含四個整數:LLL,NNN,rFr_FrF​,以及rBr_BrB​。下面NNN行描述了休息站。對於111至NNN之間的每一個iii,第i+1i+1i+1行包含了兩個整數xix_ixi​和cic_ici​,描述了第iii個休息站的位置和那裡的草的美味值。 輸入保證rF>rBr_F > r_BrF​>rB​,並且0<x1<⋯<xN<L0 < x_1 < \dots < x_N < L 0<x1​<⋯<xN​<L。注意rFr_FrF​和rBr_BrB​的單位為秒每米!

輸出格式(檔名:reststops.out): 輸出一個整數:Bessie可以獲得的最多的美味單位。

題目描述

Farmer John and his personal trainer Bessie are hiking up Mount Vancowver. For their purposes (and yours), the mountain can be represented as a long straight trail of length LLL meters (1≤L≤1061 \leq L \leq 10^61≤L≤106). Farmer John will hike the trail at a constant travel rate of rFr_FrF​ seconds per meter (1≤rF≤1061 \leq r_F \leq 10^61≤rF​≤106). Since he is working on his stamina, he will not take any rest stops along the way. Bessie, however, is allowed to take rest stops, where she might find some tasty grass. Of course, she cannot stop just anywhere! There are NNN rest stops along the trail (1≤N≤1051 \leq N \leq 10^51≤N≤105); the iii-th stop is xix_ixi​ meters from the start of the trail (0<xi<L0 < x_i < L0<xi​<L) and has a tastiness value cic_ici​ (1≤ci≤1061 \leq c_i \leq 10^61≤ci​≤106). If Bessie rests at stop iii for ttt seconds, she receives ci⋅tc_i \cdot tci​⋅t tastiness units.

When not at a rest stop, Bessie will be hiking at a fixed travel rate of rBr_BrB​ seconds per meter (1≤rB≤1061 \leq r_B \leq 10^61≤rB​≤106). Since Bessie is young and fit, rBr_BrB​ is strictly less than rFr_FrF​.

Bessie would like to maximize her consumption of tasty grass. But she is worried about Farmer John; she thinks that if at any point along the hike she is behind Farmer John on the trail, he might lose all motivation to continue!

Help Bessie find the maximum total tastiness units she can obtain while making sure that Farmer John completes the hike.

輸入輸出格式

輸入格式:

The first line of input contains four integers: LLL, NNN, rFr_FrF​, and rBr_BrB​. The next NNN lines describe the rest stops. For each iii between 111 and NNN, the i+1i+1i+1-st line contains two integers xix_ixi​ and cic_ici​, describing the position of the iii-th rest stop and the tastiness of the grass there. It is guaranteed that rF>rBr_F > r_BrF​>rB​, and 0<x1<⋯<xN<L0 < x_1 < \dots < x_N < L 0<x1​<⋯<xN​<L. Note that rFr_FrF​ and rBr_BrB​ are given in seconds per meter!

輸出格式:

A single integer: the maximum total tastiness units Bessie can obtain.

輸入輸出樣例

輸入樣例#1:

10 2 4 3
7 2
8 1

輸出樣例#1:

15

說明

In this example, it is optimal for Bessie to stop for 777 seconds at the x=7x=7x=7 rest stop (acquiring 141414 tastiness units) and then stop for an additional 111 second at the x=8x=8x=8 rest stop (acquiring 111 more tastiness unit, for a total of 151515 tastiness units).

Problem credits: Dhruv Rohatgi

題目連結

一道很簡單的貪心題。

既然給出了速度(注意題目中給出的速度是秒/米而不是米/秒),且在每個休息站能夠停下的時間無限,那麼這道題就從是貪心了(起初我還想了半天的DP)。

首先將每個休息站按照權值從大到小排序(如果權值相等就按照座標從小到大排序)。很顯然要在儘可能多的時間中在權值較大點中休息。所以每次就從當前可能的權值最大的點開始找,並記錄下上次休息的點,在這個點一直休息到另一個人追上來,再通過速度差拉開距離,到下一個權值最大的點休息。每次休息的點肯定是越來越靠後的,所以在當前點休息完之後繼續向後列舉找到一個比當前點更靠後的權值最大的點,然後開始休息。 設當前點為pos,上次休息的點為last,那麼在此處休息對答案的貢獻是w[pos]*(pos-last)*(Rf-Rb)。這個貪心的複雜度是O(n)的所以顯然能過。值得一提的是給出的L好像並沒有什麼用。

#include<cstdio>
#include<algorithm>
#include<iostream>
#include<cstring>
#define p 1000000007
#define LL long long
using namespace std;
inline LL read()
{
    LL sum=0;
    char ch =getchar();
    while(ch<'0'||ch>'9')
        ch=getchar();
    while(ch>='0'&&ch<='9')
    {
        sum=sum*10+ch-'0';
        ch=getchar();
    }
    return sum;
}
int l,n;
LL rb,rf,ans=0;
struct station
{
    int pos;
    LL w;
}h[100005];
bool cmp(const station &a,const station &b)
{
    if(a.w==b.w) return a.pos<b.pos;
    return a.w>b.w;
}
int main()
{
    l=read();n=read();
    rf=read();rb=read();
    for(register int i=1;i<=n;++i)
    {
        h[i].pos=read();
        h[i].w=read();
    }
    sort(h+1,h+n+1,cmp);
    int maxr=0;
    for(register int i=1;i<=n;++i)
    {
        if(h[i].pos>maxr)
        {
            ans+=h[i].w*(h[i].pos-maxr)*(rf-rb);
            maxr=h[i].pos;
        }
    }
    cout<<ans<<endl;
    return 0;
}