hdu6249 dp+贪心

Alice’s Stamps
Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 1038 Accepted Submission(s): 367

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.

Source
2017中国大学生程序设计竞赛-总决赛-重现赛(感谢哈工大)

Recommend
liuyiding
题意:给出n个点,m条线段,每条线段可以覆盖li到ri,问选取k条线段,可以得到的最多的可以覆盖的点的个数。
做法:dp,但是这个dp有点玄学,它不需要保证每个状态都是对的,它保证了结果需要的那部分dp是对的。
dp[i][j]代表前i个点j选取j个线段可以得到的最多的覆盖。在dp中,可以假设每次选取一条线段,必定要走到这条线段的最后(不一定是从这条线段最左端开始选),那么dp在状态转移的时候只需要保证每个线段的结束点是最优的,然后这些结束点中,只需要保证一些点是最优的,举例,假设当前点在x,有y条线段经过了x,那么我们只需要考虑x跳到每条线段的最右端的状态的转移,因为上面证明了跳到最后可以保证最优,然后又很多个选择,因为有y条线段经过了x,但是根据题意,我们只需要保证x跳到这些线段中最右的那个点,这个点肯定比其他的点优,所有我们舍弃其他的点,保证x可以跳到的最右的那个点最优就可以了。这样每次状态转移只需要1次,就可以保证结果是最优的,但是过程中不保证每个状态是最优的,只保证需要的节点的状态是最优的。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
using namespace std;
const int maxn = 2000+5;

int n,m,k;
int dp[maxn][maxn];

struct node
{
    int l,r;
    bool operator< (const node& rhs) const
    {
        return l<rhs.l;
    }
}s[maxn];

int main()
{
    //freopen("in.txt","r",stdin);
    int T;
    int kase = 0;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d%d%d",&n,&m,&k);
        for(int i=1;i<=m;i++)
            scanf("%d%d",&s[i].l,&s[i].r);
        memset(dp,0,sizeof(dp));
        sort(s+1,s+m+1);
        int pos = 1, num = 0;
        for(int i=0;i<n;i++)
        {
            while(pos<=m && s[pos].l==i+1)
            {
                num = max(num, s[pos].r - s[pos].l + 1);
                pos++;
            }

            for(int j=0;j<=k;j++)
            {
                dp[i+1][j] = max(dp[i][j],dp[i+1][j]);
                dp[i+num][j+1] = max(dp[i][j]+num,dp[i+num][j+1]);
            }
            if(num)   num--;  //因为左端点右移了一位,所以这里需要
        }
        printf("Case #%d: ",++kase);
        printf("%d\n",dp[n][k]);
    }
    return 0;
}
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值