E. Lunar New Year and Red Envelopes

26 篇文章 0 订阅
9 篇文章 0 订阅

题目链接:http://codeforces.com/problemset/problem/1106/E

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 11 and 55, collecting 1313 coins in total.

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

题意:就是有k个红包,每个红包都有起止时间,和选了之后d时间内不能再选,还有它的价值,所有的时间都在n以内,然后有m次机会干扰红包的选择,求可以获得最小红包的价值。

思路:由于条件的限制,dp是很用以想到的但如何设计状态,却有点难。我们可以设计一个状态dp[i][j]以时间i结尾,用了j次可以获取的最小值。

那么dp转移方程就可以这样考虑

如果在i时间内存在满足条件的红包则dp[d+1][j=min(dp[d+1][j],dp[i][j]+w[i]);

如果有干扰则dp[i+1][j+1]=min(dp[i+1][j+1],dp[i][j]);

如果不存在

则dp[i+1][j]=min(dp[i][j,dp[i+1][j]);

怎么找出满足条件的红包呢

通过题意可知用优先队列维护即可,但为了保证所有小于i的时间的红包都可以选到(这个时间是起始时间)。所以要先进行排序(按起始时间)。

代码:

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue>
#define LL long long
#define INF 1e18

using namespace std;
const int maxn=1e5+100;
const int maxm=250;
LL dp[maxn][maxm];
struct node
{
    int s,e,d;
    LL w;
    bool operator <(const node &rhs) const
    {
        if(w==rhs.w)
        {
            return d<rhs.d;
        }
        return w<rhs.w;
    }
};

node b[maxn];
bool cmp(node tt1,node tt2)
{
    return tt1.s<tt2.s;
}
int main()
{
    int n,k,m;
    scanf("%d%d%d",&n,&m,&k);
    for(int i=1;i<=k;i++)
    {
        scanf("%d%d%d%lld",&b[i].s,&b[i].e,&b[i].d,&b[i].w);
    }
    sort(b+1,b+1+k,cmp);
    for(int i=0;i<=n+1;i++)
    {
        for(int j=0;j<=m+1;j++)
        {
            dp[i][j]=INF;
           // cout<<dp[i][j]<<" ";
        }
        //cout<<endl;
    }
    dp[1][0]=0;
    int tot=1;
    priority_queue<node>Q;
    for(int i=1;i<=n;i++)
    {
        //cout<<i<<endl;
        while(tot<=k&&b[tot].s<=i)
        {
            Q.push(b[tot]);
            tot++;
        }
        node p;
        if(!Q.empty())
        {
            p=Q.top();
            while(p.e<i&&!Q.empty())
            {
                Q.pop();
                p=Q.top();
            }
        }
        for(int j=0;j<=m;j++)
        {
            if(Q.empty())
            {
                dp[i+1][j]=min(dp[i+1][j],dp[i][j]);
            }
            else
            {
                dp[i+1][j+1]=min(dp[i+1][j+1],dp[i][j]);
                p=Q.top();
                /*if(p.d+1==11)
                {
                    cout<<p.w<<endl;
                }*/
                dp[min(p.d+1,n+1)][j]=min(dp[min(p.d+1,n+1)][j],dp[i][j]+p.w);

            }
        }
    }
    LL ans=dp[n+1][0];
   /* for(int i=1;i<=n+1;i++)
    {
        for(int j=0;j<=m;j++)
        {
            printf("%lld ",dp[i][j]);
            //ans=min(ans,dp[n+1][i]);
        }
        printf("\n");
    }*/
    for(int j=0;j<=m;j++)
    {
        ans=min(ans,dp[n+1][j]);
    }
    printf("%lld\n",ans);
    return 0;
}

总结:这个题是dp加贪心

 

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值