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

题目大意:

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

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

接下来k行描述红包 s t d w;(1≤s≤t≤d≤n , 1≤w≤1e9)

表示在 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\n",DFS(1,0));
    }

    return 0;
}

原文地址:https://www.cnblogs.com/zquzjx/p/10345461.html

时间: 2024-08-01 17:04:14

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

Codeforces 39E What Has Dirichlet Got to Do with That? 博弈+记忆化搜索

题目链接:点击打开链接 题意: 给定 a个箱子 b个球 常数n (球和箱子都是各不相同的,不会出现有一样的物品) 设 way = 把b个球放到a个箱子中的方法数, 若way >= n则游戏结束 有2个人玩游戏. 若当前轮到 X时 1. X选择增加一个箱子或增加一个球 2.若增加完后方法数>=n 则X失败 若先手必胜,则输出 Masha ,若先手必败则输出 Stas ,若为平局则输出 Missing 思路: 记忆化搜索 若当前给 a++ 或 b++都是会>=n 则当前局势必败 从其中不会&

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

Problem  Codeforces Round #536 (Div. 2) - D. Lunar New Year and a Wander Time Limit: 3000 mSec Problem Description Input Output Output a line containing the lexicographically smallest sequence a1,a2,…,an Bob can record. Sample Input 3 21 21 3 Sample

Codeforces Round #536 (Div. 2)

目录 Codeforces Round #536 (Div. 2) A 题目大意 题解 卡点 C++ Code: B 题目大意 题解 卡点 C++ Code: C 题目大意 题解 卡点 C++ Code: D 题目大意 题解 卡点 C++ Code: E 题目大意 题解 卡点 C++ Code: F 题目大意 题解 卡点 C++ Code: Codeforces Round #536 (Div. 2) A 题目大意 给你一个\(n\times n(n\leqslant500)\)的矩阵,只包含.

Codeforces Div.301D Bad Luck Island(概率dp+记忆化搜索)

一道概率dp问题. 题目链接:http://codeforces.com/contest/540/problem/D 题目大意:一个岛上有r个石头,s个剪子,p个布,他们之间随机挑出两个相遇,如果不是相同物种,就会有一个消失,分别求出最后这座岛上只剩下一个物种的概率. 我们用dp[i][j][k]来存储i个石头,j个剪刀,k个布时,某物种的存活概率,共dp三次,算出三个物种分别的概率. 首先,我们需要把对应想求的物种概率初始化,这里以石头为例,那么对于i从1到r,不难理解dp[i][0][0]=

POJ 3252 Round Numbers(数位dp&amp;amp;记忆化搜索)

题目链接:[kuangbin带你飞]专题十五 数位DP E - Round Numbers 题意 给定区间.求转化为二进制后当中0比1多或相等的数字的个数. 思路 将数字转化为二进制进行数位dp,由于一个二进制数的最高位必须为1.所以设置变量first记录前面位是否有1,若有1,则可随意放,否则,仅仅可放1. 同一时候.上面的推断决定了搜索时len的大小与二进制本身的长度不一定相等,所以需两个变量对1和0的个数进行记录. 用dp[a][b][c]保存长度a,b个0,c个1的数字个数.记忆化搜索.

Codeforces 509F Progress Monitoring (区间dp 或 记忆化搜索)

F. Progress Monitoring time limit per test 1 second memory limit per test 256 megabytes Programming teacher Dmitry Olegovich is going to propose the following task for one of his tests for students: You are given a tree T with n vertices, specified b

Codeforces 148D Bag of mice:概率dp 记忆化搜索

题目链接:http://codeforces.com/problemset/problem/148/D 题意: 一个袋子中有w只白老鼠,b只黑老鼠. 公主和龙轮流从袋子里随机抓一只老鼠出来,不放回,公主先拿. 公主每次抓一只出来.龙每次在抓一只出来之后,会随机有一只老鼠跳出来(被龙吓的了...). 先抓到白老鼠的人赢.若两人最后都没有抓到白老鼠,则龙赢. 问你公主赢的概率. 题解: 表示状态: dp[i][j] = probability to win(当前公主先手,公主赢的概率) i:剩i只白

Codeforces 294B Shaass and Bookshelf(记忆化搜索)

题目 记忆化搜索(深搜+记录状态) 感谢JLGG //记忆话搜索 //一本书2中状态,竖着放或者横着放 //初始先都竖着放,然后从左边往右边扫 #include<stdio.h> #include<string.h> #include<algorithm> using namespace std; int dp[110][210][210];//dp[第几个][厚度][宽度] int n; int a[110],b[110]; int rec(int i,int th,

UVA - 10559 Blocks 和 Vasya and Binary String CodeForces - 1107E (dp OR 记忆化搜索)

UVA - 10559 Blocks 题意:消消乐,每次连续相同的可以消除,分数加上长度的平方,问最多可以获得几分全部消完 题解: 区间dp + 记忆化搜索 dp[i][j][k] : (区间 [i,  j] 后面带上一段和 j 颜色相同的且长度为 k )的消消乐最大积分 1.消最后一段颜色和 j 颜色相同的 dp[i][j][k] <-- dp[i][j-1][0] + (k+1)^2 2.对于i <= l < j, 如果 l 和 j 的颜色相同, 那么可以把 [l+1, j-1]消掉