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]
翰林课程体验,退费流程快速投诉邮箱: yuxi@linstitute.net 沪ICP备2023009024号-1