HDU 6249 Alice’s Stamps (dp)

Alice’s Stamps

Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 1169    Accepted Submission(s): 417


 

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个区间最多能覆盖多少个点。

思路:

刚开始想线段树,无奈出题人丧心病狂,卡掉了多一个log的线段树。

于是只能考虑n^2的dp。dp的状态表示还是很好想的:

设dp[i][j]为右端点为i点,选j个区间所能覆盖的最大点数。

显然dp[i][j]要转移到dp[k][j+1],就必须i+1点到k点是被一条线段覆盖的,即你选的这条线段,而且k就是你选的这条线段的右端点。

对于每个点i,我们希望选的下一条线段能增加尽可能多的未覆盖的点。因此在输入每条线段时,标记每个点的值为覆盖这个点的所有线段中右端点能延伸的最大值。设为you[i]

则就有

if(you[i+1]) dp[you[i+1]][j]=max(dp[you[i+1]][j],dp[i][j-1]+you[i+1]-i);
if(i) dp[i][j]=max(dp[i][j],dp[i-1][j]);
dp[i][j]=max(dp[i][j],dp[i][j-1]);

然后代码就很简单了:(有疑问欢迎在评论区留言)

#include<bits/stdc++.h>
using namespace std;
const int maxn=2010;
int n,m,k;
struct line
{
    int l,r;
}a[maxn];
int you[maxn],dp[maxn][maxn];
int main()
{
    int i,j,cns,t;
    scanf("%d",&t);
    cns=1;
    while(t--)
    {
        scanf("%d%d%d",&n,&m,&k);
        memset(you,0,sizeof(you));
        for(i=0;i<m;i++)
        {
            scanf("%d%d",&a[i].l,&a[i].r);
            for(int j=a[i].l;j<=a[i].r;j++)
            you[j]=max(you[j],a[i].r);
        }
        memset(dp,0,sizeof(dp));
        for(int i=0;i<n;i++)
        for(int j=1;j<=k;j++)
        {
            if(you[i+1]) dp[you[i+1]][j]=max(dp[you[i+1]][j],dp[i][j-1]+you[i+1]-i);
            if(i) dp[i][j]=max(dp[i][j],dp[i-1][j]);
            dp[i][j]=max(dp[i][j],dp[i][j-1]);
        }
        int ans=0;
        for(int i=1;i<=n;i++)
        for(int j=1;j<=k;j++)
        ans=max(ans,dp[i][j]);
        printf("Case #%d: ",cns++);
        printf("%d\n",ans);
    }
}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值