CF1106E Lunar New Year and Red Envelopes

Posted huangchenyan

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CF1106E Lunar New Year and Red Envelopes相关的知识,希望对你有一定的参考价值。

set预处理+DP

对于每一个时间点,记录开始于此时间的红包和结束于此时间的红包

那么在$O(n)$的复杂度就可以处理出每一个时间点的红包

然后将这些红包插入$set$中,以$w$为第一关键字,$d$为第二关键字排序

每次取出$set$中最大元素即是当前父亲要选的红包

 

现在Alice会打扰其父亲,所以记$dp[i][j]$表示第$i$个时间点前,Alice打扰了$j$次时,父亲取到钱的最小值

那么对于这道题来说填表法比较复杂,所以考虑刷表法

对于一个时间点Alice可以选择打扰或不打扰

 

如果打扰,$dp[i][j]$可以转移到$dp[i+d][j$],$d$为当前选择红包的$d$值

如果不打扰,$dp[i][j]$可以转移到$dp[i+1][j+1]$

#include <bits/stdc++.h>
#define ll long long
#define inf 1e18
using namespace std;
const ll MAXN=1e5+100;
ll n,m,k,dp[MAXN][210],mt;
struct node

    ll s,t,d,w,key;
sh[MAXN];
vector <node> be[MAXN],ed[MAXN];
multiset <node> s;//需要用多重集合,考虑重复
bool operator < (node a,node b)

    return (a.w>b.w || a.w==b.w && a.d>b.d || a.w==b.w && a.d==b.d && a.key<b.key);

int main()

    srand(time(0));
    scanf("%lld%lld%lld",&n,&m,&k);
    for (ll i=1;i<=k;i++)
      scanf("%lld%lld%lld%lld",&sh[i].s,&sh[i].t,&sh[i].d,&sh[i].w);
    for (ll i=1;i<=k;i++)
      sh[i].key=rand();//表示随机选择
    for (ll i=1;i<=k;i++)
    
        ed[sh[i].t].push_back(sh[i]);
        be[sh[i].s].push_back(sh[i]);//记录开始的红包和结束的红包
    
    for (ll i=1;i<=n+1;i++)
    
        for (ll j=0;j<=m;j++)
          dp[i][j]=inf;
    
    dp[1][0]=0;//初始打扰次数为0
    for (ll i=1;i<=n;i++)
    
        multiset <node> :: iterator it;
        for (ll j=0;j<(ll)ed[i-1].size();j++)
        
            it=s.lower_bound(ed[i-1][j]);
            s.erase(it);
        
        for (ll j=0;j<(ll)be[i].size();j++)
          s.insert(be[i][j]);
        if (s.empty())
        
            for (ll j=0;j<=min(i-1,m);j++)
              dp[i+1][j]=min(dp[i+1][j],dp[i][j]);
        
        else
        
            node g;
            g=*s.begin();
            for (ll j=0;j<=min(i-1,m);j++)
            
                if (j!=m)//注意边界
                
                    dp[i+1][j+1]=min(dp[i+1][j+1],dp[i][j]);
                    dp[g.d+1][j]=min(dp[g.d+1][j],dp[i][j]+g.w);
                
                else
                
                    dp[g.d+1][j]=min(dp[g.d+1][j],dp[i][j]+g.w);
                
            
        
    
    ll ans=inf;
    for (ll i=0;i<=m;i++)
      ans=min(ans,dp[n+1][i]);
    printf("%lld\n",ans);

 

以上是关于CF1106E Lunar New Year and Red Envelopes的主要内容,如果未能解决你的问题,请参考以下文章

CF1106F Lunar New Year and a Recursive Sequence

CF - 1106 E Lunar New Year and Red Envelopes DP

CF1106F Lunar New Year and a Recursive Sequence——矩阵快速幂&&bsgs

CF1106F Lunar New Year and a Recursive Sequence(矩阵快速幂+bsgs+exgcd)

CF1106F Lunar New Year and a Recursive Sequence 原根矩阵快速幂高次剩余BSGS

Codeforces Round #536 (Div. 2) - D. Lunar New Year and a Wander(最短路)