之前看错题目了,以为父亲的选择时按最大收益来的。结果并不是
/*
注意题目中说只要某个时间父亲可以取得红包,他就取硬币数最多同时耗时最小的那个
就是不管后续如何,不一定满足最大收益
dp[i][j]表示时间i被干扰j次所得的最小收益
dp[i][j]=dp[a+1][j]+b; <a,b>是时间i可取的价值最大同时耗时最小的红包,这是必定取的
dp[i][j]=min(dp[i][j],dp[i+1][j-1])决定是否进行干扰
由状态转移方程可以看出,前面时间的状态是由后面时间的状态取得的,所以外层i循环从后往前
*/
#include<bits/stdc++.h> #include<set> #include<vector> using namespace std; #define maxn 100005 #define ll long long ll dp[maxn][205],n,m,k; vector<pair<ll,ll> >S[maxn],E[maxn]; multiset<pair<ll,ll> >s;//默认是从小到大排序的,由于要取出的是价值最大的元素,所以在存入时把w存为-w int main(){ cin>>n>>m>>k; for(int i=1;i<=k;i++){ ll s,t,d,w; cin>>s>>t>>d>>w; S[s].push_back(make_pair(-w,-d)); E[t].push_back(make_pair(-w,-d)); } memset(dp,0,sizeof dp); for(int i=n;i>=1;i--){ for(int j=0;j<E[i].size();j++)s.insert(E[i][j]); pair<ll,ll> t=make_pair(0,0); ll a,b; if(!s.empty()){ t=*s.begin(); b=-t.first;a=-t.second+1; } else a=i+1,b=0; for(int j=0;j<=m;j++){ dp[i][j]=dp[a][j]+b;//未被干扰的决策 if(j)dp[i][j]=min(dp[i][j],dp[i+1][j-1]); } for(int j=0;j<S[i].size();j++)s.erase(s.find(S[i][j])); } printf("%lld ",dp[1][m]); }