Lunar New Year and Red Envelopes CodeForces - 1106E (dp)

大意: 总共$n$的时间, $k$个红包, 红包$i$只能在时间$[s_i,t_i]$范围内拿, 并且拿完后时间跳到$d_i+1$,Bob采用贪心策略,每个时间点若有红包能取则取钱数$w_i$最大的, $w_i$相同则取$d_i$最大的, Alice有$m$次机会让Bob跳过一个时间, 求Alice如何操作能使Bob得到钱数最少.

比较简单的DP, 记$dp[i][j]$为$i$时刻还能干扰$j$次的最小收益

$dp[i][j]=min(dp[d_i][j]+w_i,dp[i+1][j-1])$, $(w_i,d_i)$为$i$时刻的贪心策略

用一个堆维护一个最优的(w,d)来转移即可

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <math.h>
#include <set>
#include <map>
#include <queue>
#include <string>
#include <string.h>
#define REP(i,a,n) for(int i=a;i<=n;++i)
#define PER(i,a,n) for(int i=n;i>=a;--i)
#define hr putchar(10)
#define pb push_back
#define lc (o<<1)
#define rc (lc|1)
#define mid ((l+r)>>1)
#define ls lc,l,mid
#define rs rc,mid+1,r
#define w first
#define d second
#define io std::ios::sync_with_stdio(false)
#define endl ‘\n‘
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
const int P = 1e9+7, INF = 0x3f3f3f3f;
ll gcd(ll a,ll b) {return b?gcd(b,a%b):a;}
ll qpow(ll a,ll n) {ll r=1%P;for (a%=P;n;a=a*a%P,n>>=1)if(n&1)r=r*a%P;return r;}
ll inv(ll x){return x<=1?1:inv(P%x)*(P-P/x)%P;}
//head

const int N = 1e5+10;

int n, m, k, t;
struct _ {
	int s,t,d,w;
	bool operator < (const _ &rhs) const {
		return pii(w,d) < pii(rhs.w,rhs.d);
	}
} a[N];
ll dp[N][202];
priority_queue<_> q;

int main() {
	scanf("%d%d%d", &n, &m, &k);
	REP(i,1,k) {
		scanf("%d%d%d%d",&a[i].s,&a[i].t,&a[i].d,&a[i].w);
	}
	sort(a+1,a+1+k,[](_ a,_ b){return a.t<b.t;});
	memset(dp,0x3f,sizeof dp);
	REP(i,0,m) dp[n+1][i]=0;
	int now = k;
	PER(i,1,n) {
		while (now>0&&a[now].t>=i) q.push(a[now--]);
		while (q.size()&&q.top().s>i) q.pop();
		if (q.empty()) {
			REP(j,0,m) dp[i][j]=dp[i+1][j];
			continue;
		}
		int d=q.top().d,w=q.top().w;
		dp[i][0] = dp[d+1][0]+w;
		REP(j,1,m) dp[i][j]=min(dp[d+1][j]+w,dp[i+1][j-1]);
	}
	printf("%lld\n", dp[1][m]);
}

原文地址:https://www.cnblogs.com/uid001/p/10504135.html

时间: 2024-10-09 00:00:53

Lunar New Year and Red Envelopes CodeForces - 1106E (dp)的相关文章

【Codeforces 1106E】Lunar New Year and Red Envelopes

[链接] 我是链接,点我呀:) [题意] 给你k个红包,每个红包可以在si..ti的时间范围内拿走. 抢完红包之后你得到wi元,然后你需要在di+1时刻才能继续抢红包 时间是线性的从1..n 然后某个人可以阻止你在x时刻抢红包,然后你的时间跳过1s(-1s)直接到达x+1时刻. 这个人可以阻止你m次. 请问这个人采用最优阻止策略下,你最少抢到的金额. (如果有多个可以抢的红包,那么抢wi最大的,如果仍然相同抢di最大的,再相同的话就无所谓了,因为选哪个都一样了) [题解] dp 设dp[i][j

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维护在某个时间点可获得的红包有

CF - 1106 E Lunar New Year and Red Envelopes DP

题目传送门 题解: 首先要处理出每个时间点会选择哪一个线段. 对于这个问题,可以用multiset去维护信息. 当时间线开始的时候,往mutiset里面插入这个信息,当时间线结束的时候,删除这个信息. 每次只要取出最大位就好了. 然后,就是状态转移,注意的就是只有转移进来过的状态才能转移出去. 代码: /* code by: zstu wxk time: 2019/02/03 */ #include<bits/stdc++.h> using namespace std; #define Fop

codeforces 449D DP+容斥

Jzzhu and Numbers Time Limit:2000MS     Memory Limit:262144KB     64bit IO Format:%I64d & %I64u Submit Status Appoint description:  System Crawler  (2014-07-20) Description Jzzhu have n non-negative integers a1, a2, ..., an. We will call a sequence o

CodeForces 706C dp

C - Hard problem Time Limit:1000MS     Memory Limit:262144KB     64bit IO Format:%I64d & %I64u Submit Status Practice CodeForces 706C Description Vasiliy is fond of solving different tasks. Today he found one he wasn't able to solve himself, so he as

【BZOJ1419】 Red is good [期望DP]

Red is good Time Limit: 10 Sec  Memory Limit: 64 MB[Submit][Status][Discuss] Description 桌面上有R张红牌和B张黑牌,随机打乱顺序后放在桌面上,开始一张一张地翻牌,翻到红牌得到1美元,黑牌则付出1美元.可以随时停止翻牌,在最优策略下平均能得到多少钱. Input 一行输入两个数R,B. Output 在最优策略下平均能得到多少钱.输出答案时,小数点后第六位后的全部去掉,不要四舍五入. Sample Input

codeforces的dp专题

1.(467C)http://codeforces.com/problemset/problem/467/C 题意:有一个长为n的序列,选取k个长度为m的子序列(子序列中不能有位置重复),求所取的k个序列求和的最大值是多少 分析:设dp[i][j]在[j,n]范围内取了i个子序列求和所得的最大值,用sum[i]表示[1,i]的求和.转移方程为dp[i][j]=max(dp[i-1][j+m]+sum[j+m-1]-sum[j-1],dp[i][j+1]),表示要不要选择[j,j+m-1]这段为其

计蒜客 Red Black Tree(树形DP)

You are given a rooted tree with n nodes. The nodes are numbered 1..n. The root is node 1, and m of the nodes are colored red, the rest are black. You would like to choose a subset of nodes such that there is no node in your subset which is an ancest

codeforces 830E dp

大致题意: n场比赛,k个钱币.赢一场获得一个钱币,输一场失去一个钱币,一旦钱币数量为2k个或者0个,就马上离开比赛.给出n个长度字符串,由W,D,L,?四个字符组成,W表示赢,L表示输,D表示平局,?表示前三种情况的一种. 问此字符串是否是合法的赛事,如果合法,输出其中任意一种情况. 分析: 状态定义:d[i][j]表示前i场比赛,W-L=j,是否合法,合法为1,不合法为0 状态转移:if(s[i]=='D') d[i][j]=d[i-1][j]; else if(s[i]=='W') d[i