題意:現在有 個紅包,總共 的時間, 採用貪心策略,每個時間點若有紅包能取則取錢數 最多的,且取完之後直到 個時間點之後才能再取紅包, 有 次機會在一個時間點讓 不能做任何操作, 怎麼分配這 次機會才能使得 獲得的錢數最少,問最少的錢數爲多少。
思路:很明顯是 ,狀態爲第 個時間點, 用了 次機會。對於每個點 要選擇的紅包,可以通過優先隊列每次更新。由於 所以對於一個時間點若選取第 個紅包,則影響的狀態的時間點優先隊列裏已經不存在第 個紅包,所以直接 即可。
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <queue>
#include <string>
#include <cmath>
using namespace std;
#define ll long long
#define PI acos(-1)
#define INF 0x3f3f3f3f
#define NUM 100005
#define debug true
#define lowbit(x) ((-x)&x)
#define ffor(i,d,u) for(int i=(d);i<=(u);++i)
#define _ffor(i,u,d) for(int i=(u);i>=(d);--i)
#define mst(array,Num,Kind,Count) memset(array,Num,sizeof(Kind)*(Count))
int n, m, k;
struct node
{
int s, t, d;
long long w;
bool operator<(const node &x)const
{
if (w != x.w)
return w < x.w;
return d < x.d;
}
}r[NUM];
long long dp[NUM][205];
priority_queue<node, vector<node>, less<node> > p;
template <typename T>
inline void read(T &x){
char ch = getchar();x = 0;
for (; ch < '0' || ch > '9'; ch = getchar());
for (; ch >='0' && ch <= '9'; ch = getchar()) x = x * 10 + ch - '0';
}
template <typename T>
inline void write(T x)
{
int len=0;char c[21];
if(x<0)putchar('-'),x*=(-1);
do{++len;c[len]=(x%10)+'0';}while(x/=10);
_ffor(i,len,1)putchar(c[i]);
}
inline bool cmp(const node &x, const node &y)
{
return x.s < y.s;
}
inline void AC()
{
int h = 1;
node x;
dp[0][0] = 0;
read(n), read(m), read(k);
ffor(i, 1, k) read(r[i].s), read(r[i].t), read(r[i].d), read(r[i].w);
ffor(i, 1, n)
ffor(j, 0, min(i, m))
dp[i][j] = 100000000000005;
sort(r + 1, r + 1 + k, cmp);
ffor(i, 0, n)
{
while (h <= k && r[h].s <= i + 1)//壓入可以選擇的紅包
{
p.push(r[h]);
++h;
}
if (!p.empty())//彈出已經超過時間點的紅包
{
x = p.top();
while (x.t < i + 1)
{
p.pop();
if (p.empty())
break;
x = p.top();
}
}
ffor(j, 0, min(i, m))
if(p.empty())//當前時間點沒有紅包可以選擇
dp[i + 1][j] = min(dp[i + 1][j], dp[i][j]);
else
{
dp[x.d][j] = min(dp[i][j] + x.w, dp[x.d][j]);//Bob選擇紅包
dp[i + 1][j + 1] = min(dp[i + 1][j + 1], dp[i][j]);//Alice使用一次機會
}
}
long long ans = dp[n][0];
ffor(i, 1, min(n, m)) ans = min(ans, dp[n][i]);
write(ans);
}
int main()
{
AC();
return 0;
}