• Codeforces Round #536 E. Lunar New Year and Red Envelopes /// 贪心 记忆化搜索 multiset取最大项


    题目大意:

    给定n m k;(1≤n≤1e5, 0≤m≤200, 1k1e5)

    表示n个时间长度内 最多被打扰m次 k个红包

    接下来k行描述红包 s t d w;(1std1w1e9

    表示在 s 到 t 的时间内都可开始获得该红包

    该红包在时间 d 时才能完成获得 红包内有w硬币

    在同一时间段内只能获得一个红包 不能同时获得两个及以上

    求在被打扰的情况下使获得的红包硬币最少 是多少

    用in out标记各红包可被获得的区间 

    用multiset维护在某个时间点可获得的红包有哪些 (放入in内的 去掉out内的)

    multiset内部按w排序 那么在某个时间点取出w最大的就是获得红包的贪心策略 .rbegin()可获得multiset/set内的最后一项

    按时间点记忆化搜索一下 dp[ 时间点 ][ 被打扰次数 ]来记忆

    以上存储信息要用pair<> 用结构体会MLE

    #include <bits/stdc++.h>
    using namespace std;
    #define INF 0x3f3f3f3f
    #define LL long long
    #define mem(i,j) memset(i,j,sizeof(i))
    #define pb push_back
    #define mp(i,j) make_pair(i,j)
    #define fir first
    #define sec second
    #define P pair<LL,LL>
    const int N=1e5+5;
    P best[N]; // best[i] 在i位置的最佳策略
    LL n, m, k;
    LL dp[N][205];
    // 记忆化 dp[i][j]在i位置被打扰了j次能获得的最少硬币
    multiset <P> now;
    // 维护当前位置所有能取的红包 pair默认按first排序
    vector <P> in[N], out[N];
    // in为从该位置开始可取的 out为从该位置开始不可取的
    
    void init() {
        mem(dp,-1); now.clear();
        for(int i=1;i<=n+1;i++)
            in[i].clear(), out[i].clear();
    }
    LL DFS(int ind,int c) {
        if(ind>n) return 0LL;
        if(dp[ind][c]>=0LL) return dp[ind][c];
        LL res=best[ind].fir+DFS(best[ind].sec+1,c); // 取这个红包
        if(c<m) res=min(res,DFS(ind+1,c+1)); // 被女儿阻止
        return dp[ind][c]=res;
    }
    
    int main()
    {
        while(~scanf("%d%d%d",&n,&m,&k)) {
            init();
            for(int i=0;i<k;i++) {
                LL l,r,d,w;
                scanf("%I64d%I64d%I64d%I64d",&l,&r,&d,&w);
                in[l].pb(mp(w,d));
                out[r+1].pb(mp(w,d));
            }
            for(int i=1;i<=n+1;i++) {
                for(int j=0;j<in[i].size();j++)
                    now.insert(in[i][j]); // 加入可取的
                for(int j=0;j<out[i].size();j++)
                    now.erase(now.find(out[i][j])); // 去掉不可取的
                if(now.size()) best[i]=*now.rbegin(); // 最佳策略是w最大的
                else best[i]={0LL,(LL)i};
            }
            printf("%I64d
    ",DFS(1,0));
        }
    
        return 0;
    }
    View Code
  • 相关阅读:
    zabbix短信网关调用问题总结
    zabbix短信接口调用
    Windows Open with Sublime Text
    [转载]windows下安装Python虚拟环境virtualenvwrapper-win
    Resilio-sync auto restart
    django-orm-standalone
    RabbitMQ笔记
    RabbitMQ启动出错:- unable to connect to epmd on xxxx: timeout (timed out)
    [Python笔记]第十六篇:web框架之Tornado
    [前端笔记]第三篇:JavaScript
  • 原文地址:https://www.cnblogs.com/zquzjx/p/10345461.html
Copyright © 2020-2023  润新知