1. 程式人生 > >CF - 1106 E Lunar New Year and Red Envelopes DP

CF - 1106 E Lunar New Year and Red Envelopes DP

最大 tar first fop using bit con scanf 技術

題目傳送門

題解:

首先要處理出每個時間點會選擇哪一個線段。

對於這個問題,可以用multiset去維護信息。

當時間線開始的時候,往mutiset裏面插入這個信息,當時間線結束的時候,刪除這個信息。

每次只要取出最大位就好了。

然後,就是狀態轉移,註意的就是只有轉移進來過的狀態才能轉移出去。

代碼:

技術分享圖片
/*
code by: zstu wxk
time: 2019/02/03
*/
#include<bits/stdc++.h>
using namespace std;
#define Fopen freopen("_in.txt","r",stdin); freopen("_out.txt","w",stdout);
#define
LL long long #define ULL unsigned LL #define fi first #define se second #define pb push_back #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 #define lch(x) tr[x].son[0] #define rch(x) tr[x].son[1] #define max3(a,b,c) max(a,max(b,c)) #define min3(a,b,c) min(a,min(b,c)) typedef pair<int
,int> pll; const int inf = 0x3f3f3f3f; const int _inf = 0xc0c0c0c0; const LL INF = 0x3f3f3f3f3f3f3f3f; const LL _INF = 0xc0c0c0c0c0c0c0c0; const LL mod = (int)1e9+7; const int N = 1e5 + 100; int n, m, k; struct Node{ int d, w; bool operator < (const Node & x) const{ if(w == x.w) return d > x.d;
return w > x.w; } }; vector<Node> in[N], out[N]; LL dp[N][210]; multiset<Node> st; void Ac(){ for(int i = 1; i <= k; ++i){ int s, t, d, w; scanf("%d%d%d%d", &s, &t, &d, &w); in[s].pb({d,w}); out[t].pb({d,w}); } memset(dp, INF, sizeof dp); dp[1][0] = 0; for(int i = 1; i <= n; ++i){ for(Node & x : in[i]){ st.insert(x); for(int j = 0; j <= m; ++j){ if(dp[i][j] == INF) continue; dp[i+1][j+1] = min(dp[i+1][j+1], dp[i][j]); if(st.empty()) dp[i+1][j] = min(dp[i+1][j], dp[i][j]); else { Node x = *st.begin(); dp[x.d+1][j] = min(dp[x.d+1][j], dp[i][j]+x.w); } } for(Node &x : out[i]) st.erase(st.lower_bound(x)); } LL ans = INF; for(int j = 0; j <= m; ++j) ans = min(ans, dp[n+1][j]); printf("%I64d\n", ans); } int main(){ while(~scanf("%d%d%d", &n, &m, &k)){ Ac(); } return 0; }
View Code

CF - 1106 E Lunar New Year and Red Envelopes DP