codeforces1106e(优先队列+dp)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_25576697/article/details/86750338

传送门:http://codeforces.com/problemset/problem/1106/E

E. Lunar New Year and Red Envelopes

time limit per test

3 seconds

memory limit per test

256 megabytes

input

standard input

output

standard output

Lunar New Year is approaching, and Bob is going to receive some red envelopes with countless money! But collecting money from red envelopes is a time-consuming process itself.

Let's describe this problem in a mathematical way. Consider a timeline from time 11 to nn. The ii-th red envelope will be available from time sisi to titi, inclusive, and contain wiwi coins. If Bob chooses to collect the coins in the ii-th red envelope, he can do it only in an integer point of time between sisi and titi, inclusive, and he can't collect any more envelopes until time didi (inclusive) after that. Here si≤ti≤disi≤ti≤di holds.

Bob is a greedy man, he collects coins greedily — whenever he can collect coins at some integer time xx, he collects the available red envelope with the maximum number of coins. If there are multiple envelopes with the same maximum number of coins, Bob would choose the one whose parameter dd is the largest. If there are still multiple choices, Bob will choose one from them randomly.

However, Alice — his daughter — doesn't want her father to get too many coins. She could disturb Bob at no more than mm integer time moments. If Alice decides to disturb Bob at time xx, he could not do anything at time xx and resumes his usual strategy at the time x+1x+1(inclusive), which may lead to missing some red envelopes.

Calculate the minimum number of coins Bob would get if Alice disturbs him optimally.

Input

The first line contains three non-negative integers nn, mm and kk (1≤n≤1051≤n≤105, 0≤m≤2000≤m≤200, 1≤k≤1051≤k≤105), denoting the length of the timeline, the number of times Alice can disturb Bob and the total number of red envelopes, respectively.

The following kk lines describe those kk red envelopes. The ii-th line contains four positive integers sisi, titi, didi and wiwi (1≤si≤ti≤di≤n1≤si≤ti≤di≤n, 1≤wi≤1091≤wi≤109) — the time segment when the ii-th envelope is available, the time moment Bob can continue collecting after collecting the ii-th envelope, and the number of coins in this envelope, respectively.

Output

Output one integer — the minimum number of coins Bob would get if Alice disturbs him optimally.

Examples

input

Copy

5 0 2
1 3 4 5
2 5 5 8

output

Copy

13

input

Copy

10 1 6
1 1 2 4
2 2 6 2
3 3 3 3
4 4 4 5
5 5 5 7
6 6 6 9

output

Copy

2

input

Copy

12 2 6
1 5 5 4
4 6 6 2
3 8 8 3
2 9 9 5
6 10 10 7
8 12 12 9

output

Copy

11

Note

In the first sample, Alice has no chance to disturb Bob. Therefore Bob will collect the coins in the red envelopes at time 1 and 5, collecting 13 coins in total.

In the second sample, Alice should disturb Bob at time 1. Therefore Bob skips the first envelope, collects the second one and can not do anything after that. So the answer is 2.

题意:有1-n这n个时间点,有k个红包,每个红包都有自己的属性,分别为可以领取的时间si~ti,领取后直到di时刻不能领取其他红包,每个红包都有对应的金额wi。A采取贪心的策略,在1-n的时间点中,每次都领取能领取的金额最大的红包,如果金额一样就领取冷却时间最长的红包。

另一个人B有m次干扰A的机会,每次选择一个时间点干扰A,那么A在这个时间点就不能领红包,直到下一个时间点才能恢复,继续贪心。

求A在B干扰下能获得的最少的金额。

 

思路:

好久没有做题了。。

题目挺拗口的。。。

参考了一下其他大佬的博客。主要是这篇:https://blog.csdn.net/Mitsuha_/article/details/86738613

所以代码都写的差不多。。。。

首先,假如没有干扰要算A能获得的金额要怎么算?

我们可以将红包按照他的起始时间来排序,再设定一个指针代表当前时间,在1-n滑动,当在一个时间T时,将所有起始时间小于等于这个时间的红包放到(金额大冷却长优先的)优先队列中,然后从队头取出结束时间大于等于T的一个红包,在总金额上加上他的金额,跳转到冷却时间后一个时间T‘重复工作,直到没有红包或者时间跳出范围。

现在,能够disturb,那么就需要dp来转移。

dp[i][j]代表在i时间点前使用了j次disturb所能获得的最少的金额。

那么:

1.对于时间点T没有红包可以拿,这个金额就顺延到下一个时刻T+1

          dp[i+1][j] = dp[i][j]

2.如果有红包可以拿,有两种转移方式:

a.不disturb:那么就拿了红包,转移到d+1时间点。

          dp[min(n+1,d+1)][j] = min(dp[min(n+1,d+1)][j],dp[i][j] + w)

b.如果还有disturb的机会:就可以不拿红包,转移到T+1时间点。

         dp[min(n+1,T+1)][j+1] = min(dp[min(n+1,T+1)][j+1],dp[i][j])

这里优先队列主要是用来计算时刻T能领取的红包

#include<iostream>
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<queue>
#include<math.h>
using namespace std;
typedef long long ll;
const int maxn = 1e5+10;
int n,m,k;
struct node
{
    int s,t,d;
    ll w;
    bool operator<(const node x)const{
        if(w==x.w)return d<x.d;
        return w<x.w;
    } 
}elps[maxn];
priority_queue<node>q;
bool cmp(const node&a,const node&b){
    return a.s<b.s;
}
ll dp[maxn][210];
int main()
{
    scanf("%d%d%d",&n,&m,&k);
    for(int i = 1;i<=k;i++)
    {
        scanf("%d%d%d%I64d",&elps[i].s,&elps[i].t,&elps[i].d,&elps[i].w);
    }
    sort(elps+1,elps+1+k,cmp);
    memset(dp,-1,sizeof(dp));
    dp[1][0] = 0;
    int it = 1;
    for(int i = 1;i<=n;i++)
    {
        while(it<=k&&elps[it].s<=i)
        {
            q.push(elps[it]),it++;
        }
        while(!q.empty()&&q.top().t<i)q.pop();
        if(q.empty())
        {
            for(int j = 0;j<=m;j++)
            {
                if(dp[i][j]==-1)continue;
                if(dp[i+1][j]!=-1)
                    dp[i+1][j] = min(dp[i+1][j],dp[i][j]);
                else
                    dp[i+1][j] = dp[i][j];
            }
        }
        else
        {
            node now = q.top();
            for(int j = 0;j<=m;j++)
            {
                if(dp[i][j]==-1)continue;
                if(dp[min(n+1,now.d+1)][j]!=-1)
                    dp[min(n+1,now.d+1)][j] = min(dp[min(n+1,now.d+1)][j],dp[i][j] + now.w);
                else
                    dp[min(n+1,now.d+1)][j] = dp[i][j] + now.w;
                if(j<m)
                {
                    if(dp[min(n+1,i+1)][j+1]!=-1)
                        dp[min(n+1,i+1)][j+1] = min(dp[min(n+1,i+1)][j+1],dp[i][j]);
                    else
                        dp[min(n+1,i+1)][j+1] = dp[i][j];
                }
            }
        }
    }
    ll ans = dp[n+1][0];
    for(int j = 1;j<=m;j++)
        ans = min(ans,dp[n+1][j]);
    ans = max(ans,0ll);
    printf("%I64d\n",ans);
}

 

展开阅读全文

没有更多推荐了,返回首页