armer John has?MM?cows, conveniently labeled?1…M1…M, who enjoy the occasional change of pace from eating grass. As a treat for the cows, Farmer John has baked?NN?pies (1≤N≤3001≤N≤300), labeled?1…N1…N. Cow?ii?enjoys pies with labels in the range?[li,ri][li,ri]?(from?lili?to?riri?inclusive), and no two cows enjoy the exact same range of pies. Cow?ii?also has a weight,?wiwi, which is an integer in the range?1…1061…106.
Farmer John may choose a sequence of cows?c1,c2,…,cK,c1,c2,…,cK,?after which the selected cows will take turns eating in that order. Unfortunately, the cows don't know how to share! When it is cow?cici's turn to eat, she will consume all of the pies that she enjoys --- that is, all remaining pies in the interval?[lci,rci][lci,rci]. Farmer John would like to avoid the awkward situation occurring when it is a cows turn to eat but all of the pies she enjoys have already been consumed. Therefore, he wants you to compute the largest possible total weight (wc1+wc2+…+wcKwc1+wc2+…+wcK) of a sequence?c1,c2,…,cKc1,c2,…,cK?for which each cow in the sequence eats at least one pie.
The first line contains two integers?NN?and?MM?(1≤M≤N(N+1)2)(1≤M≤N(N+1)2).The next?MM?lines each describe a cow in terms of the integers?wi,liwi,li, and?riri.
Print the maximum possible total weight of a valid sequence.
2 2 100 1 2 100 1 1
200
In this example, if cow 1 eats first, then there will be nothing left for cow 2 to eat. However, if cow 2 eats first, then cow 1 will be satisfied by eating the second pie only.
Problem credits: Benjamin Qi
<h3>USACO 2019 December Contest, Platinum Problem 1. Greedy Pie Eaters? 题解(翰林国际教育提供,仅供参考)</h3>
<p style="text-align: center;">题解请<a href="/register" target="_blank" rel="noopener">注册</a>或<a href="/login" target="_blank" rel="noopener">登录</a>查看</p>
[/hide]
(Analysis by Benjamin Qi)
Subtask 1:
We can use bitmask DP and construct the sequence in order. Let?curcur?be the bitmask representing the cows which have already been chosen and let?res[cur]res[cur]?be the maximum possible length of the sequence for this state. Furthermore, let?mask[cur]mask[cur]?be the bitmask representing the pies that are chosen by these cows and?tot[i]tot[i]?be the bitmask representing the pies which cow?ii?enjoys. Then we can only add cow?ii?to the sequence if?mask[cur]≠(mask[cur]&tot[i])mask[cur]≠(mask[cur]&tot[i]).
It's easy to implement a solution that runs in?O(M2M)O(M2M)?time.
Subtask 2:
Any reasonable solution which is polynomial in?NN?should pass.
Subtask 3:
We can solve this problem in?O(N3).O(N3).?Let?dp[l][r]dp[l][r]?denote the maximum number of cows such that the set of eaten pies is a?subset?of the range?l…r.l…r.?Then we can write
Furthermore, suppose that the last cow in the sequence ate pie?ii?for some?l≤i≤r.l≤i≤r.?Then if there exists an interval?[a,b][a,b]?such that?l≤a≤i≤b≤r,l≤a≤i≤b≤r,?we can write
where?mx[i][l][r]mx[i][l][r]?is the maximum weight over all cows?[li,ri][li,ri]?satisfying?l≤li≤i≤ri≤r.l≤li≤i≤ri≤r.?Our answer will be the value of?dp[0][N?1].dp[0][N?1].
This DP can be computed in?O(N3)O(N3)?time.
#include <bits/stdc++.h> using namespace std; typedef long long ll; typedef vector<int> vi; #define FOR(i,a,b) for (int i = (a); i < (b); ++i) #define F0R(i,a) FOR(i,0,a) #define ROF(i,a,b) for (int i = (b)-1; i >= (a); --i) #define R0F(i,a) ROF(i,0,a) #define trav(a,x) for (auto& a: x) #define pb push_back #define rsz resize #define sz(x) int(x.size()) template<class T> bool ckmax(T& a, const T& b) { return a < b ? a = b, 1 : 0; } void setIO(string name) { ios_base::sync_with_stdio(0); cin.tie(0); freopen((name+".in").c_str(),"r",stdin); freopen((name+".out").c_str(),"w",stdout); } const int MX = 300; int N,M,dp[MX][MX]; int mx[MX][MX][MX]; vi w,l,r; int main() { setIO("pieaters"); cin >> N >> M; w.rsz(M); l.rsz(M), r.rsz(M); F0R(i,M) { cin >> w[i] >> l[i] >> r[i]; l[i] --,r[i] --; FOR(j,l[i],r[i]+1) ckmax(mx[j][l[i]][r[i]],w[i]); } F0R(i,N) { R0F(j,i+1) FOR(k,i,N) { if (j) ckmax(mx[i][j-1][k],mx[i][j][k]); if (k < N-1) ckmax(mx[i][j][k+1],mx[i][j][k]); } } R0F(a,N) FOR(b,a,N) { FOR(c,a,b) ckmax(dp[a][b],dp[a][c]+dp[c+1][b]); FOR(c,a,b+1) if (mx[c][a][b]) { // among all those covering c >= a int res = mx[c][a][b]; if (c > a) res += dp[a][c-1]; if (c < b) res += dp[c+1][b]; ckmax(dp[a][b],res); } } cout << dp[0][N-1] << "\n"; }
[/hide]
? 2025. All Rights Reserved. 沪ICP备2023009024号-1