zoukankan      html  css  js  c++  java
  • 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
  • 相关阅读:
    Unity3d资源管理分析
    Unity3D之MonoBehaviour的可重写函数整理
    Unity3D脚本学习——运行时类
    A*寻路初探(转载)
    360sdk网游支付服务
    总结使用Unity 3D优化游戏运行性能的经验
    Unity3D之Lightmap详解
    「luogu2714」四元组统计
    「BZOJ1066」[SCOI2007]蜥蜴
    「luogu1251」餐巾计划问题
  • 原文地址:https://www.cnblogs.com/zquzjx/p/10345461.html
Copyright © 2011-2022 走看看