codeforces 115E Linear Kingdom Races 線段樹 + DP 好題

來源:互聯網
上載者:User

參考了這裡 http://blog.sina.com.cn/s/blog_6a6aa7830100x890.html

題意:有N條賽道,每一條初始時都是壞的,修複第i條賽道的費用是cost[i];賽道上會舉辦m個賽事,每個賽事會用到[L,R]之間的賽道,而且要保證賽事進行必須使得這一段的賽道完好,每項賽事還可以獲得一定的錢數。問題要求安排哪些比賽可以使得收益最大。

可以設dp[i]表示到i這個賽道為止能獲得最大的利益

有狀態轉移方程

dp[i]=max(dp[i-1],dp[j]+benefit[j+1][i]-mend[j+1][i]);

註: j+1->i之間有賽道

資料範圍200000 暴力的話顯然逾時,所以可以考慮用某種資料結構最佳化一下,我用了線段樹

做法:

先把m項賽事按右端點遞增排個序,這樣就可以將以同一個端點結束的賽事一起考慮,去更新前面的DP【】

一項賽事[L,R] 能影響的DP值肯定是在L之前的,即 dp【1~L-1】,要不然比賽場地都不完整,無法獲利

還有就是每一次枚舉到某段賽道i時,都要對前面所有的DP值 - cost[R],即dp[1~R-1]都減cost[R],  當我們選用所有的以同一個點結尾的賽道時,

dp[L-1]+benefit[L][R]-mend[L][R],獲利之前必須先承受L+1~R這段路的維修費用

然後dp[1~L-1]都可以加上L - >R賽道帶來的獲利,所以給1->L-1這段的DP值加上benefit[L][R],

然後線段樹還有一個作用就是查詢這個區間的最大值,即更新之後最大的DP值Max[1]

dp[i]=max(dp[i-1],Max[1]);

然後將求得的DP值插入線段樹中i位置即可

以下是代碼

View Code

#include<cstdio>#include<cstring>#include<algorithm>using namespace std;#define lson L,R,val,l,m,x<<1#define rson L,R,val,m+1,r,x<<1|1typedef __int64 lld;const int maxn = 200010;struct seg{    int l,r;    lld val;    bool operator <(const seg &cmp) const{        return r<cmp.r;    }}ss[maxn];int cost[maxn];lld dp[maxn],Max[maxn<<2],add[maxn<<2];lld max(lld a,lld b){    return a>b?a:b;}void pushup(int x){    Max[x]=max(Max[x<<1],Max[x<<1|1]);}void pushdown(int x){    if(add[x]){        add[x<<1]+=add[x];        add[x<<1|1]+=add[x];        Max[x<<1]+=add[x];        Max[x<<1|1]+=add[x];        add[x]=0;    }}void update(int L,int R,lld  val,int l,int r,int x){    if(L<=l&&r<=R){        add[x]+=val;        Max[x]+=val;        return ;    }    pushdown(x);    int m=(l+r)>>1;    if(L<=m) update(lson);    if(R>m) update(rson);    pushup(x);}int main(){    int n,m,i,j;    while(scanf("%d%d",&n,&m)!=EOF)    {        for(i=1;i<=n;i++) scanf("%d",&cost[i]);        for(i=0;i<m;i++) scanf("%d%d%I64d",&ss[i].l,&ss[i].r,&ss[i].val);        sort(ss,ss+m);        memset(add,0,sizeof(add));        memset(Max,0,sizeof(Max));        dp[0]=0;        for(i=1,j=0;i<=n;i++)        {            update(0,i-1,-cost[i],0,n,1);            while(ss[j].r==i&&j<m)            {                update(0,ss[j].l-1,ss[j].val,0,n,1);                j++;            }            dp[i]=max(dp[i-1],Max[1]);            update(i,i,dp[i],0,n,1);        }        printf("%I64d\n",dp[n]);    }    return 0;}

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.