61级的题

dp

#include<cstdio> 
#include<algorithm> 
inline int read() { 
    int x = 0,f = 1; 
    char c = getchar(); 
    while(c < '0' || c > '9')c = getchar();
    while(c <= '9' && c >= '0') x = x * 10 + c - '0',c = getchar(); 
    return x * f; 
} 
const int maxn = 100007; 
int n,k; 
struct Seg { 
    int l, r; 
    bool operator < (const Seg &a)const { 
        return r == a.r ? l < a.l : r < a.r; 
    } 
} seg[maxn  << 1]; 
int dp[maxn][2],pmax[maxn],q[maxn],dq[maxn]; 
int main() { 
    freopen("cover9.in","r",stdin); 
    n = read(),k = read(); 
    for(int i = 1;i <= n;++ i) { 
        seg[i].l = read(), seg[i].r = read(); 
    } std::sort(seg + 1, seg + n + 1); 
    int cnt = 1; 
    for(int i = 2;i <= n;++ i) { 
        while(seg[i].l <= seg[cnt].l) cnt --; 
        seg[++ cnt] = seg[i]; 
    } 
    //for(int i = 1;i <= cnt;++ i) printf("%d %d\n",seg[i].l,seg[i].r); 
    n = cnt; 
    int now = 0,ans = 0; 
    for(int i = 1;i <= n;++ i) dp[i][now] = std::max(seg[i].r - seg[i].l,dp[i - 1][now]);  
    
    for(int i = 2;i <= k;++ i) { 
        pmax[0] = -0x3f3f3f3f; 
        for(int j = 1;j <= n;++ j) pmax[j] = std::max(dp[j][now],pmax[j - 1]); 
        for(int j = 1;j <= n;++ j) dq[j] = dp[j][now] - seg[j].r; 
        now ^= 1; 
        int lc = 0,h = 1,t = 0; if(i == 2) q[++ t] = 1; 
        for(int j = i ;j <= n;++ j) { 
            while(seg[lc].r <= seg[j].l) lc ++; lc --; 
            dp[j][now] = pmax[lc] + seg[j].r - seg[j].l; 
            while(h <= t && q[h] <= lc) h ++; 
            if(h <= t) dp[j][now] = std::max(dp[j][now] ,dq[q[h]] + seg[j].r); 
            while(h <= t && dq[q[t]] <= dq[j]) -- t; q[++ t] = j; 
            ans = std::max(ans,dp[j][now]); 
        } 
    } 
    printf("%d\n",ans); 
    return 0; 
} 
  
  

猜你喜欢

转载自www.cnblogs.com/sssy/p/9452024.html
61