HDU6249 Alice’s Stamps(2017CCPC-Final,dp)

版权声明:本作品采用知识共享署名-非商业性使用 4.0 国际许可协议进行许可。 https://blog.csdn.net/riba2534/article/details/84309557

Problem Description

Alice likes to collect stamps. She is now at the post office buying some new stamps.
There are N different kinds of stamps that exist in the world; they are numbered 1 through N. However, stamps are not sold individually; they must be purchased in sets. There are M different stamp sets available; the ith set contains the stamps numbered Li through Ri. The same stamp might appear in more than one set, and it is possible that one or more stamps are not available in any of the sets.
All of the sets cost the same amount; because Alice has a limited budget, she can buy at most K different sets. What is the maximum number of different kinds of stamps that Alice can get?

Input

The input starts with one line containing one integer T, the number of test cases.T test cases follow.
Each test case begins with a line containing three integers: N, M, and K: the number of different kinds of stamps available, the number of stamp sets available, and the maximum number of stamp sets that Alice can buy.
M lines follow; the ithoftheselinesrepresentsthei^{th} stamp set and contains two integers, Li and Ri, which represent the inclusive range of the numbers of the stamps available in that set.
1≤T≤100
1≤K≤M
1≤N,M≤2000
1≤Li≤Ri≤N

Output

For each test case, output one line containing “Case #x: y”, where x is the test case number (starting from 1) and y is the maximum number of different kinds of stamp that Alice could get.

Sample Input

2
5 3 2
3 4
1 1
1 3
100 2 1
1 50
90 100

Sample Output

Case #1: 4
Case #2: 50

Hint

In sample case #1, Alice could buy the first and the third stamp sets, which contain the first four kinds
of stamp. Note that she gets two copies of stamp 3, but only the number of different kinds of stamps
matters, not the number of stamps of each kind.
In sample case #2, Alice could buy the first stamp set, which contains 50 different kinds of stamps.

思路

给你 N , M , K N,M,K 代表有从 1 1 N N 这个区间的数字,然后接下来给出 M M 段区间,每段题目给出这段区间的左右端点,然后你要从中选择 K K 个区间,最后使得选择的所有段中数字种类最多,输出最多种类,段可以重叠。

我们考虑 d p dp 思路:

定义:

  • dp[i][j]代表从1~i之间选择j个区间所能达到的最大数字种类数
  • 然后我们记录一下每一个数字向右能到达的最右端点,记为t[i]

最后可以得到状态转移方程:

当这一个点被某一个区间包含的时候:
	dp[t[i]][j]=max(dp[t[i]][j],dp[i-1][j-1]+当前区间覆盖的范围)
dp[i][j]=max(dp[i][j],dp[i-1][j])

最后求出所有的dp[i][j]的最大值即可,复杂度为 O ( n 2 ) O(n^2)

代码

#include <bits/stdc++.h>
using namespace std;
#define mem(a, b) memset(a, b, sizeof(a))
const int N = 2005;
int dp[N][N]; //dp[i][j]代表前i个点选j个区间所能达到的最大数字数量
int t[N];
void solve()
{
    mem(t, 0), mem(dp, 0);
    int n, m, k;
    scanf("%d%d%d", &n, &m, &k);
    int x, y;
    for (int i = 0; i < m; i++)
    {
        scanf("%d%d", &x, &y);
        for (int i = x; i <= y; i++)
            t[i] = max(t[i], y); 
    }
    for (int i = 1; i <= n; i++) 
    {
        for (int j = 1; j <= k; j++)
        {
            if (t[i]) 
                dp[t[i]][j] = max(dp[i - 1][j - 1] + t[i] - (i - 1), dp[t[i]][j]);
            dp[i][j] = max(dp[i][j], dp[i - 1][j]);
        }
    }
    int ans = 0;
    for (int i = 1; i <= n; i++)
        for (int j = 1; j <= k; j++)
            ans = max(ans, dp[i][j]);
    printf("%d\n", ans);
}
int main()
{
    freopen("in.txt", "r", stdin);
    //freopen("1.out", "w", stdout);
    int t, q = 1;
    scanf("%d", &t);
    while (t--)
    {
        printf("Case #%d: ", q++);
        solve();
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/riba2534/article/details/84309557