zoukankan      html  css  js  c++  java
  • 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
    ",ans);
    }
  • 相关阅读:
    Swift
    美国绿卡
    H-1-B签证简介
    托福、雅思和GRE的区别
    使用fdisk命令对linux硬盘进行操作
    Welcome to Workrave
    Installing patches on an ESXi 5.x by the command
    How to install VIB on VMware ESXi
    Robocopy用法
    Location of ESXi 5.1 log files
  • 原文地址:https://www.cnblogs.com/huangchenyan/p/11247364.html
Copyright © 2011-2022 走看看