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; 
} 
  
  

posted @ 2018-08-09 22:01  zzzzx  阅读(91)  评论(0编辑  收藏  举报