ZOJ 3941 Kpop Music Party (贪心+思维+枚举)

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 day and 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.

题意:

给你n(n<=10)个闭区间,k(k<=1e9),你要从给你的这些区间中挑选m(m<=1e9)个点,假设挑选了点x,那么你会获得[x,x+k-1]中所有的点(每个点只有一个,获得后仍可挑选)。问你最多能获得多少个不同的点。

思路:

我觉得这题难度还是比较高的,但是过了不少人。。。好吧还是我菜

考虑先把所有区间按左端点排序合并成互不相交的闭区间,从第一个区间的左端点开始挑选互不相交的长度为k的闭区间。

如果m还有剩余,那么很显然如果再选某些区间的右端点,会使答案增加

因为区间数<=10,因此我们直接枚举每个区间的右端点选或不选即可。

上述过程可用一个dfs来实现,用pos表示当前挑选到的最右边的点的坐标为pos,res为当前获得点的个数,sum为当前挑选的点的个数。注意考虑到选取右端点时答案的计算。

代码:

#include<bits/stdc++.h>
#define ll long long
#define inf 0x3f3f3f3f
#define rep(i,a,b) for(register int i=(a);i<=(b);i++)
#define dep(i,a,b) for(register int i=(a);i>=(b);i--)
using namespace std;
const int maxn=2010;
ll n,m,k;
ll fg,ans;
ll ok[maxn];
int cnt;
struct node
{
    ll l,r;
    bool operator<(node aa)const
    {
        return l<aa.l||(l==aa.l&&r<aa.r);
    }
}c[maxn],a[maxn];
void dfs(int i,ll pos,ll res,ll sum)
{
    if(sum>m) return;
    if(sum==m||i==cnt+1){ans=max(ans,res);return;}
    ll len,pos1,tp,tp1;
    if(pos<a[i].r)
    {
        len=min(a[i].r-a[i].l+1,a[i].r-pos);
        tp=(len+k-1)/k;
        if(sum+tp>m) ans=max(ans,res+(m-sum)*k);
        pos1=max(a[i].l+tp*k-1,pos+tp*k);
        dfs(i+1,pos1,res+tp*k,sum+tp);
        dfs(i+1,a[i].r+k-1,res+tp*k+a[i].r-(pos1-k+1),sum+tp+1);
    }
    else if(pos>=a[i].r)
    {
        dfs(i+1,pos,res,sum);
        dfs(i+1,a[i].r+k-1,res+a[i].r-(pos-k+1),sum+1);
    }
}
int main()
{
    int T,cas=1;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%lld%lld%lld",&n,&k,&m);
        rep(i,1,n)
        scanf("%lld%lld",&c[i].l,&c[i].r);
        sort(c+1,c+1+n);
        cnt=0;
        memset(ok,0,sizeof(ok));
        a[++cnt].l=c[1].l;
        ll pos=c[1].r;
        rep(i,1,n)
        {
            if(c[i].l<=pos+1)
            {
                pos=max(pos,c[i].r);
            }
            else
            {
                a[cnt++].r=pos;
                a[cnt].l=c[i].l;
                pos=c[i].r;
            }
        }
        a[cnt].r=pos;
        //rep(i,1,cnt)
        //cout<<a[i].l<<" * "<<a[i].r<<endl;
        ans=0;
        dfs(1,0,0,0);
        printf("%lld\n",ans);
    }
    return 0;
}
/*
666
6 5 7
1 1
4 5
7 8
11 11
13 19
20 24
*/

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值