题目链接:http://codeforces.com/problemset/problem/1106/E
Lunar New Year is approaching, and Bob is going to receive some red envelopes with countless money! But collecting money from red envelopes is a time-consuming process itself.
Let's describe this problem in a mathematical way. Consider a timeline from time 11 to nn. The ii-th red envelope will be available from time sisi to titi, inclusive, and contain wiwi coins. If Bob chooses to collect the coins in the ii-th red envelope, he can do it only in an integer point of time between sisi and titi, inclusive, and he can't collect any more envelopes until time didi (inclusive) after that. Here si≤ti≤disi≤ti≤di holds.
Bob is a greedy man, he collects coins greedily — whenever he can collect coins at some integer time xx, he collects the available red envelope with the maximum number of coins. If there are multiple envelopes with the same maximum number of coins, Bob would choose the one whose parameter dd is the largest. If there are still multiple choices, Bob will choose one from them randomly.
However, Alice — his daughter — doesn't want her father to get too many coins. She could disturb Bob at no more than mm integer time moments. If Alice decides to disturb Bob at time xx, he could not do anything at time xx and resumes his usual strategy at the time x+1x+1(inclusive), which may lead to missing some red envelopes.
Calculate the minimum number of coins Bob would get if Alice disturbs him optimally.
Input
The first line contains three non-negative integers nn, mm and kk (1≤n≤1051≤n≤105, 0≤m≤2000≤m≤200, 1≤k≤1051≤k≤105), denoting the length of the timeline, the number of times Alice can disturb Bob and the total number of red envelopes, respectively.
The following kk lines describe those kk red envelopes. The ii-th line contains four positive integers sisi, titi, didi and wiwi (1≤si≤ti≤di≤n1≤si≤ti≤di≤n, 1≤wi≤1091≤wi≤109) — the time segment when the ii-th envelope is available, the time moment Bob can continue collecting after collecting the ii-th envelope, and the number of coins in this envelope, respectively.
Output
Output one integer — the minimum number of coins Bob would get if Alice disturbs him optimally.
Examples
input
Copy
5 0 2 1 3 4 5 2 5 5 8
output
Copy
13
input
Copy
10 1 6 1 1 2 4 2 2 6 2 3 3 3 3 4 4 4 5 5 5 5 7 6 6 6 9
output
Copy
2
input
Copy
12 2 6 1 5 5 4 4 6 6 2 3 8 8 3 2 9 9 5 6 10 10 7 8 12 12 9
output
Copy
11
Note
In the first sample, Alice has no chance to disturb Bob. Therefore Bob will collect the coins in the red envelopes at time 11 and 55, collecting 1313 coins in total.
In the second sample, Alice should disturb Bob at time 11. Therefore Bob skips the first envelope, collects the second one and can not do anything after that. So the answer is 22.
题意:就是有k个红包,每个红包都有起止时间,和选了之后d时间内不能再选,还有它的价值,所有的时间都在n以内,然后有m次机会干扰红包的选择,求可以获得最小红包的价值。
思路:由于条件的限制,dp是很用以想到的但如何设计状态,却有点难。我们可以设计一个状态dp[i][j]以时间i结尾,用了j次可以获取的最小值。
那么dp转移方程就可以这样考虑
如果在i时间内存在满足条件的红包则dp[d+1][j=min(dp[d+1][j],dp[i][j]+w[i]);
如果有干扰则dp[i+1][j+1]=min(dp[i+1][j+1],dp[i][j]);
如果不存在
则dp[i+1][j]=min(dp[i][j,dp[i+1][j]);
怎么找出满足条件的红包呢
通过题意可知用优先队列维护即可,但为了保证所有小于i的时间的红包都可以选到(这个时间是起始时间)。所以要先进行排序(按起始时间)。
代码:
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue>
#define LL long long
#define INF 1e18
using namespace std;
const int maxn=1e5+100;
const int maxm=250;
LL dp[maxn][maxm];
struct node
{
int s,e,d;
LL w;
bool operator <(const node &rhs) const
{
if(w==rhs.w)
{
return d<rhs.d;
}
return w<rhs.w;
}
};
node b[maxn];
bool cmp(node tt1,node tt2)
{
return tt1.s<tt2.s;
}
int main()
{
int n,k,m;
scanf("%d%d%d",&n,&m,&k);
for(int i=1;i<=k;i++)
{
scanf("%d%d%d%lld",&b[i].s,&b[i].e,&b[i].d,&b[i].w);
}
sort(b+1,b+1+k,cmp);
for(int i=0;i<=n+1;i++)
{
for(int j=0;j<=m+1;j++)
{
dp[i][j]=INF;
// cout<<dp[i][j]<<" ";
}
//cout<<endl;
}
dp[1][0]=0;
int tot=1;
priority_queue<node>Q;
for(int i=1;i<=n;i++)
{
//cout<<i<<endl;
while(tot<=k&&b[tot].s<=i)
{
Q.push(b[tot]);
tot++;
}
node p;
if(!Q.empty())
{
p=Q.top();
while(p.e<i&&!Q.empty())
{
Q.pop();
p=Q.top();
}
}
for(int j=0;j<=m;j++)
{
if(Q.empty())
{
dp[i+1][j]=min(dp[i+1][j],dp[i][j]);
}
else
{
dp[i+1][j+1]=min(dp[i+1][j+1],dp[i][j]);
p=Q.top();
/*if(p.d+1==11)
{
cout<<p.w<<endl;
}*/
dp[min(p.d+1,n+1)][j]=min(dp[min(p.d+1,n+1)][j],dp[i][j]+p.w);
}
}
}
LL ans=dp[n+1][0];
/* for(int i=1;i<=n+1;i++)
{
for(int j=0;j<=m;j++)
{
printf("%lld ",dp[i][j]);
//ans=min(ans,dp[n+1][i]);
}
printf("\n");
}*/
for(int j=0;j<=m;j++)
{
ans=min(ans,dp[n+1][j]);
}
printf("%lld\n",ans);
return 0;
}
总结:这个题是dp加贪心