Subtask 1:
We can use bitmask DP and construct the sequence in order. Let $cur$ be the bitmask representing the cows which have already been chosen and let $res[cur]$ be the maximum possible length of the sequence for this state. Furthermore, let $mask[cur]$ be the bitmask representing the pies that are chosen by these cows and $tot[i]$ be the bitmask representing the pies which cow $i$ enjoys. Then we can only add cow $i$ to the sequence if $mask[cur]\neq (mask[cur]\&tot[i])$.
It's easy to implement a solution that runs in $O(M2^M)$ time.
Subtask 2:
Any reasonable solution which is polynomial in $N$ should pass.
Subtask 3:
We can solve this problem in $O(N^3).$ Let $dp[l][r]$ denote the maximum number of cows such that the set of eaten pies is a subset of the range $l\ldots r.$ Then we can write
This DP can be computed in $O(N^3)$ 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";
}