【ZOJ3941 The 13th Zhejiang Provincial Collegiate Programming ContestF】【贪心 暴力】Kpop Music Party n段part

Kpop Music Party Time Limit: 2 Seconds      Memory Limit: 65536 KB

Marjar University often hosts Kpop music festival. A Kpop music festival will last several days. During a Kpop festival, there will be a Kpop party every day. Kpop music is very popular all over the world, so there may be more than one Kpop music festival being hosted simultaneously.

Edward, the headmaster of Marjar University, is always obsessed with Kpop music. He will be very excited continuously for K days after attending a Kpop music party. More specifically, If he attends a Kpop party in the i-th day, he would be very excited from the i-th day to the (i + K - 1)-th day (inclusive). But the excitatory state does not stack. For example, if K is 5 and Edward attended a party in Day 1 and a party in Day 3, he will be very excited only from Day 1 to Day 7.

Edward has got the schedule of N Kpop music festivals in Marjar University. Each Kpop music festival lasts one or more days. The i-th Kpop festival starts at the Si-th dayand ends at the Ei-th day (inclusive). Due to restrictions on the discipline for the headmaster, he can attend at most M Kpop parties. Now he wants to maximize the number of days being excited. Can you help him?

Input

There are multiple test cases.The first line of input is an integer T (≤ 1000)indicating the number of test cases. For each test case:

The first line contains three integers, N, K and M.

The next N lines, each line contains two integers Si and Ei(1 ≤ N ≤ 10, 1 ≤ K, M,Si, Ei ≤ 109).

Output

For each case, print the number of the most days that Edward can be excited for.

Sample Input

2
1 5 2
1 3
3 7 3
1 5
2 5
13 13

Sample Output

7
18

Hint

For the first case, the only Kpop festival lasts from Day 1 to Day 3.Edward can attend a party in Day 1 and a party in Day 3,he would be very excited from Day 1 to Day 7.Edward can be excited for 7 days at most.

For the second case, there are 3 Kpop festivals.Edward can take part in the Kpop parties in Day 1, Day 5 and Day 13.He would be very excited from Day 1 to Day 11 and from Day 13 to Day 19.Edward can be excited for 18 days at most.

Author: ZHOU, Yuchen
Source: The 13th Zhejiang Provincial Collegiate Programming Contest
#include<stdio.h> 
#include<iostream>
#include<string.h>
#include<string>
#include<ctype.h>
#include<math.h>
#include<set>
#include<map>
#include<vector>
#include<queue>
#include<bitset>
#include<algorithm>
#include<time.h>
using namespace std;
void fre() { freopen("c://test//input.in", "r", stdin); freopen("c://test//output.out", "w", stdout); }
#define MS(x,y) memset(x,y,sizeof(x))
#define MC(x,y) memcpy(x,y,sizeof(x))
#define MP(x,y) make_pair(x,y)
#define ls o<<1
#define rs o<<1|1
typedef long long LL;
typedef unsigned long long UL;
typedef unsigned int UI;
template <class T1, class T2>inline void gmax(T1 &a, T2 b) { if (b>a)a = b; }
template <class T1, class T2>inline void gmin(T1 &a, T2 b) { if (b<a)a = b; }
const int N = 0, M = 0, Z = 1e9 + 7, ms63 = 0x3f3f3f3f;
int casenum, casei;
int n, m, g, K;
pair<int, int>a[12], b[12];
void get_segment()
{
	for (int i = 1; i <= n; ++i)scanf("%d%d", &a[i].first, &a[i].second);
	sort(a + 1, a + n + 1);
	g = 0;
	int lft = a[1].first;
	int rgt = a[1].second;
	for (int i = 2; i <= n; ++i)
	{
		if (a[i].first >= lft&&a[i].second <= rgt)gmax(rgt, a[i].second);
		else
		{
			b[++g] = MP(lft, rgt);
			lft = a[i].first;
			rgt = a[i].second;
		}
	}b[++g] = MP(lft, rgt);
}
int solve(int sta)
{
	int day = m;//day表示目前我们还可以参加party的天数
	int p = 0;	//p表示当前所在的是第i天(该天未决策)
	int ans = 0;
	for (int i = 1; i <= g; ++i)
	{
		gmax(p, b[i].first);
		int need = (b[i].second - p + 1 + K - 1) / K;	//求出我们最多可以选择多少个日期作为参加party的日期
		if (day <= need) return ans += day*K;
		day -= need;
		ans += need*K;
		p += need*K;
		int last = sta & 1; sta >>= 1;
		if (last)//last==1表示我们需要额外选取最后一个日期作为参加party的日期
		{
			int nxt = b[i].second + K;
			--day;
			ans += nxt - p;
			p = nxt;
		}
	}
	return ans;
}
int main()
{
	scanf("%d", &casenum);
	for (casei = 1; casei <= casenum; ++casei)
	{
		scanf("%d%d%d", &n, &K, &m);
		get_segment();
		int top = 1 << g;
		int ans = 0;
		for (int i = 0; i < top; ++i)gmax(ans, solve(i));
		printf("%d\n", ans);
	}
	return 0;
}
/*
【trick&&吐槽】
1,比赛时首先竟然忘记了排序,我个傻叉
2,然后细节把握出错>_<,增加了一些罚时
3,严格意义上只要2^n的枚举量即可贪心AC掉这题。

【题意】
有n(10)段时间,会举行party
每个party有开始时间,结束时间,不同party举行时间可能重复。(时间范围为1~1e9)

我们一共最多可以参加m(1e9)party。
同时有一个参数K(1e9),一旦我们在第i天参加了party,我们会连续K天(即[i,i+K-1]天范围内)都happy。
问你我们如何安排参加party的时间,可以使得我们拥有尽可能多天数是happy的

【类型】
暴力+贪心

【分析】
首先,我们显然要先把party合并成不相交的日期段[b[i].first,b[i].second]
然后,我们可以做贪心。

有以下几个贪心原则——
1,对于参加party的m天中的每一天,这一天最多给我们带来的happy增益只能是K。
	一旦有一天,如果我们在这天参加party会使得我们有K的增益并不对其他天产生干扰,那么我们肯定会在这天参加party不犹豫。

2,我们会面临的决策,肯定涉及到对于每一个日期段(比如第i段)的决策。
	结合贪心原则1,如果不考虑之前决策的干扰。
	我们会选择这个日期段的——
	第1,K+1,2K+1,3K+1,...,kK+1,这些天作为我们参加party的日期,显然结果不会差。
	于是我们只要可以选,在目前区间段,必然就会选(len+K-1)/个点作为开头位置。

	然后问题来了——
	对于每一区间段的最后一个点,我们同样是可能额外选取的。
	虽然这样的选取收益达不到K,但却是有增益效果的。

	于是我们2^n枚举每一段最后一点的选取情况。
	以此来保证后续过程不受前效性影响。
	然后就可以AC这题了>_<  

【时间复杂度&&优化】
O(T2^n*n)

*/



你可能感兴趣的:(贪心,暴力,题库-ZOJ)