弱弱有两个属性a和b,这两个属性初始的时候均为0,每一天他可以通过努力,让a涨1点或b涨1点。
为了激励弱弱努力学习,我们共有n种奖励,第i种奖励有xi,yi,zi三种属性,若a ≥ xi且b ≥ yi,则弱弱在接下来的每一天都可以得到zi的分数。
问m天以后弱弱最多能得到多少分数。
输入
第一行一个两个整数n和m(1 ≤ n ≤ 1000,1 ≤ m ≤ 2000000000)。
接下来n行,每行三个整数xi,yi,zi(1 ≤ xi, yi ≤ 1000000000,1 ≤ zi ≤ 1000000)。
输出
一行一个整数表示答案。
样例输入
2 4
2 1 10
1 2 20
样例输出
50
提示
在样例中,弱弱可以这样规划:第一天a涨1,第二天b涨1,第三天b涨1,第四天a涨1。
共获得0 + 0 + 20 + 30 = 50分。
离散 + DP + 前缀和
#include <bits/stdc++.h>
using namespace std;
#define PI 3.1415926
#define sc(a) scanf("%d",&a)
#define pfs(a) printf("%d ",a)
#define pfn(a) printf("%d\n",a);
#define pfln(a) printf("%lld\n",a);
#define rep(n) for(int i = 0; i < n; i++)
#define per(n) for(int i = m-1; i >= 0; i--)
typedef long long LL;
typedef pair<int,int> P;
const int maxn = 1100;
const int mod = 1e9+7;
const int INF = 0x3f3f3f3f;
int n,m;
int x[maxn],y[maxn],z[maxn];
set<int> cntx,cnty;
map<P,int> mp;
int tx[maxn],ty[maxn];
int ti,tj;
LL v[maxn][maxn];
LL dp[maxn][maxn];
int main()
{
sc(n),sc(m);
ti = tj = 1;
rep(n) {
sc(x[i]),sc(y[i]),sc(z[i]);
if(mp.count(P(x[i],y[i])) == 0) mp[P(x[i],y[i])] = z[i];
else mp[P(x[i],y[i])] += z[i];
if(cntx.count(x[i]) == 0) cntx.insert(x[i]),tx[ti++] = x[i];
if(cnty.count(y[i]) == 0) cnty.insert(y[i]),ty[tj++] = y[i];
}
sort(tx,tx+ti);
sort(ty,ty+tj);
memset(v,0,sizeof(v));
memset(dp,0,sizeof(dp));
for(int i = 1; i < ti; i++)
for(int j = 1; j < tj; j++)
{
if(mp.count(P(tx[i],ty[j])) == 0) v[i][j] = v[i-1][j] + v[i][j-1] - v[i-1][j-1];
else v[i][j] = v[i-1][j] + v[i][j-1] - v[i-1][j-1] + mp[P(tx[i],ty[j])];
// cout << v[i][j] << endl;
}
for(int i = 0; i < ti; i++)
for(int j = 0; j < tj; j++)
{
dp[i][j+1] = max(dp[i][j+1],dp[i][j] + v[i][j] * (ty[j+1]-ty[j]-1) + v[i][j+1]);
dp[i+1][j] = max(dp[i+1][j],dp[i][j] + v[i][j] * (tx[i+1]-tx[i]-1) + v[i+1][j]);
}
LL ans = 0;
for(int i = 1; i <= ti; i++)
{
for(int j = 1; j <= tj; j++)
{
// cout << dp[i][j] << " ";
ans = max(ans,dp[i][j] + (m-tx[i]-ty[j])*v[i][j]);
}
// cout << endl;
}
pfln(ans);
return 0;
}