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?
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.
1≤T≤100
1≤K≤M
1≤N,M≤2000
1≤Li≤Ri≤N
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.
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题意:现在有编号从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\n",k,solve()); } return 0; }
posted on 2017-12-14 12:36 ZefengYao 阅读(1025) 评论(0) 编辑 收藏 举报