Codeforces Round #536 (Div. 2) E dp + set
Posted virtu0s0
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Codeforces Round #536 (Div. 2) E dp + set相关的知识,希望对你有一定的参考价值。
https://codeforces.com/contest/1106/problem/E
题意
一共有k个红包,每个红包在\([s_i,t_i]\)时间可以领取,假如领取了第i个红包,那么在\(d_i\)后才能领取下一个红包,每个红包价值\(w_i\),对方假如有机会领取红包他一定会领取,你有m次阻止对方领取的机会,问对方最少可以拿到多少红包
题解
- 定义dp[i][j]为前i秒用了j次机会让对方拿到最小价值的红包
- \(dp[i][j] - > dp[i+1][j+1]\) 假如使用阻止
- \(dp[i][j] - > dp[d[s]+1][j]\) 假如不用
- \(dp[i][j] - > dp[i+1][j]\) 这一秒没有可以领的红包
- 用set处理当前第i秒可以领的优先级最高的红包
代码
#include<bits/stdc++.h>
#define pii pair<int,int>
#define MAXN 100005
#define mk make_pair
#define inf 0x3f3f3f3f
#define ll long long
#define ft first
#define se second
using namespace std;
vector<pii>in[MAXN],out[MAXN];
multiset<pii>S;
int n,m,k,i,j,s,t,d,w;
ll dp[MAXN][205];
int main(){
cin>>n>>m>>k;
for(i=0;i<k;i++){
scanf("%d%d%d%d",&s,&t,&d,&w);
in[s].push_back(mk(w,d));
out[t+1].push_back(mk(w,d));
}
memset(dp,inf,sizeof(dp));
for(i=0;i<=m;i++)dp[1][i]=0;
for(i=0;i<=n;i++){
for(auto x:in[i])S.insert(x);
for(auto x:out[i])S.erase(S.find(x));
for(j=0;j<=m;j++){
auto p=S.begin();
if(p==S.end())
dp[i+1][j]=min(dp[i+1][j],dp[i][j]);
else{
p=S.end();p--;
dp[p->se+1][j]=min(dp[i][j]+p->ft,dp[p->se+1][j]);
dp[i+1][j+1]=min(dp[i][j],dp[i+1][j+1]);
}
}
}
cout<<dp[n+1][m];
}
以上是关于Codeforces Round #536 (Div. 2) E dp + set的主要内容,如果未能解决你的问题,请参考以下文章
Codeforces Round #536 (Div. 2)
Codeforces Round #536 (Div. 2)
Codeforces Round #536 (Div. 2) E dp + set
Codeforces Round #536 (Div. 2) - D. Lunar New Year and a Wander(最短路)
codeforces 536a//Tavas and Karafs// Codeforces Round #299(Div. 1)
Codeforces Round #536 (Div. 2) B. Lunar New Year and Food Ordering