codeforces 1106 E
作者:互联网
显然是dp啊,dp[i][j]表示到时间i打扰了j次的最小收益
显然要排序,官方题解说set没看懂,优先队列就行啊。
按照时间排序,显然这样扫的话可以保证当前时间点的点在优先队列里吧,
然后有打断和不打断两种方式。搞一下就行了。
这个题其实只要想清楚,我在每个点能选的红包是唯一的,这样子一想就变得很**了。
头脑混乱写不出来不能怪我啊,我老人家持续表演了一个月的小品了啊
1 #include <bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 struct Red{ 5 ll s,t,d,w; 6 bool operator<(const Red& a)const{ 7 if(w==a.w) 8 return d<a.d; 9 return w<a.w; 10 } 11 }r[100005]; 12 bool cmp(Red a,Red b){ 13 if(a.s==b.s){ 14 if(a.w==b.w){ 15 return a.d>b.d; 16 } 17 return a.w>b.w; 18 } 19 return a.s<b.s; 20 } 21 int n,m,k; 22 ll dp[100005][201]; 23 priority_queue<Red> q; 24 int main() { 25 ios::sync_with_stdio(false); 26 cin>>n>>m>>k; 27 for(int i=2;i<=n+1;i++)for(int j=0;j<=m;j++)dp[i][j]=1e18; 28 for(int i=1;i<=k;i++){ 29 cin>>r[i].s>>r[i].t>>r[i].d>>r[i].w; 30 } 31 sort(r+1,r+1+k,cmp); 32 int j=1; 33 for(int i=1;i<=n;i++){// 34 for(;j<=k;){ 35 if(r[j].s<=i) { 36 q.push(r[j]); 37 j++; 38 } else break; 39 } 40 while (!q.empty()&&q.top().t<i) q.pop(); 41 if(q.empty()){ 42 for(int l=0;l<=m;l++){ 43 dp[i+1][l]=min(dp[i+1][l],dp[i][l]); 44 } 45 continue; 46 } 47 Red tmp = q.top(); 48 for(int l=0;l<=m;l++) { 49 dp[min(tmp.d+1,n+1ll)][l]=min(dp[min(tmp.d+1,n+1ll)][l],dp[i][l]+tmp.w); 50 } 51 for(int l=1;l<=m;l++){ 52 dp[i+1][l]=min(dp[i+1][l],dp[i][l-1]); 53 } 54 } 55 ll ans = 1e18; 56 for(int i=0;i<=m;i++){ 57 ans = min(ans,dp[n+1][i]); 58 } 59 cout<<ans<<endl; 60 }View Code
标签:return,int,ll,codeforces,long,1106,队列,dp 来源: https://www.cnblogs.com/MXang/p/10347189.html