HDU 6249 Alice’s Stamps(2017 CCPC-Final G题,DP)

题目链接 HDU 6249

题意 给定$m$个区间,在这些区间中选出不超过$k$个,求被覆盖的点的数量的最大值。

设$f[i][j]$表示选到第$i$个点并选了$j$个区间的时候能得到的最大答案。

处理到第$i$个点的时候观察所有覆盖$i+1$这个点的线段,找到延伸到最右端的这条线段。

假设该线段延伸到$r$,那么更新$f[r][j + 1]$。

最后枚举答案即可。

#include <bits/stdc++.h>

using namespace std;

#define	rep(i, a, b)	for (int i(a); i <= (b); ++i)
#define	dec(i, a, b)	for (int i(a); i >= (b); --i)

const int N = 2010;

int T;
int ca = 0;
int f[N][N];
int l[N], r[N];
int n, m, k;
int ans;


int main(){

	scanf("%d", &T);
	while (T--){
		scanf("%d%d%d", &n, &m, &k);
		rep(i, 1, m) scanf("%d%d", l + i, r + i);
		rep(i, 0, n + 1) rep(j, 0, m + 1) f[i][j] = 0;

		f[0][0] = 0;
		rep(i, 0, n - 1){
			int rr = 0;
			rep(j, 1, m){
				if (l[j] <= i + 1) rr = max(rr, r[j]);
			}

			rep(j, 0, k) f[i + 1][j] = max(f[i + 1][j], f[i][j]);
			if (rr == 0) continue;

			rep(j, 0, k - 1) f[rr][j + 1] = max(f[rr][j + 1], f[i][j] + rr - i);
		}

		ans = 0;
		rep(i, 1, n) rep(j, 0, k) ans = max(ans, f[i][j]);
		printf("Case #%d: %d
", ++ca, ans);
	}

	return 0;
}    
原文地址:https://www.cnblogs.com/cxhscst2/p/8215537.html