zoukankan      html  css  js  c++  java
  • hdu 6249 Alice’s Stamps

    Alice’s Stamps

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


    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 ithoftheselinesrepresentsthe i^{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.
    1T100
    1KM
    1N,M2000
    1LiRiN
     
    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
     
    题意:现在有编号从1~n一共n张邮票,m种集合可选择,每个集合包含了编号[L,R]的邮票,现在要选择m个集合中的k个集合,使得收集的邮票数量尽可能的多,那么最多能收集多少邮票
    思路:对集合按照L的大小进行排序,之后即可动态规划求解,给出dp[i][j]定义:使用了j个集合选取编号1~i一共i张邮票中的邮票,选取邮票数量的最大值。
    若当前状态为dp[i][j],那么继续选择一个集合,使得从第i+1种邮票起,取得尽可能多的编号连续的邮票,设新取到的邮票数量为num,那么可以对当前状态进行转移:dp[i+num][j+1]=max{dp[i][j]+num,dp[i+num][j+1]}
    此外还有两种状态可以由dp[i][j]进行转移,分别为:
    dp[i + 1][j] = max(dp[i][j], dp[i + 1][j])
    dp[i][j + 1] = max(dp[i][j], dp[i][j + 1])
    AC代码:
    #define _CRT_SECURE_NO_DEPRECATE
    #include<iostream>
    #include<cstdio>
    #include<vector>
    #include<algorithm>
    #include<cstring> 
    #include<string>
    #include<queue>
    #include<cmath>
    #include<map>
    using namespace std;
    #define INF 0x3f3f3f3f
    #define EPS 1e-5
    const int N_MAX = 2000+15;
    int dp[N_MAX][N_MAX];//dp[i][j]:使用了j个集合选取编号1~i一共i张邮票中的邮票数量的最大值,
    int T, N, M, K;
    struct Set{
        int l, r;
        bool operator <(const Set&b) const{
            return l < b.l;
        }
    }S[N_MAX];
    
    int solve() {
        memset(dp,0,sizeof(dp));//
        sort(S, S + M);
        int pos = 0,num=0;//每次从第i张邮票起,能连续取到的最多的邮票数量为num
        for (int i = 0; i < N;i++) {
            while (pos<M&&S[pos].l==i+1) {
                num = max(num, S[pos].r - pos[S].l + 1);
                pos++;//!!
            }
            for (int j = 0; j <= K;j++) {//当前状态为dp[i][j]
                dp[i + 1][j] = max(dp[i][j], dp[i + 1][j]);
                dp[i][j + 1] = max(dp[i][j], dp[i][j + 1]);
                dp[i + num][j + 1] = max(dp[i + num][j + 1], dp[i][j] + num);
            }
            if(num)num--;//下次循环从第i+1张邮票起,num为能连续取到的最多的邮票数量,所以至少那么多
        }
        return dp[N][K];
    }
    int main() {
        scanf("%d",&T);
        int k = 0;
        while (T--) {
            scanf("%d%d%d",&N,&M,&K);//M是集合数量,K是能选的集合个数
            for (int i = 0; i < M;i++) {
                int l, r;
                scanf("%d%d",&l,&r);
                S[i].l = l,S[i].r=r;
            }
            k++;
            printf("Case #%d: %d
    ",k,solve());
        }
        return 0;
    }
     
  • 相关阅读:
    计算机专业找工作注意什么
    LU分解
    HDU2050
    牛牛与字符串border 题解(gcd)
    牛牛与交换排序 题解(双端队列模拟区间反转)
    动态最小生成树 题解(线段树+归并排序)
    系数 题解(lucas+思维)
    D. Dogeforces 题解(并查集+构造)
    Java 入土基础
    E. AZ Graph 题解(思维)
  • 原文地址:https://www.cnblogs.com/ZefengYao/p/8037079.html
Copyright © 2011-2022 走看看