题目描述:
弱弱有两个属性aaa和bbb,这两个属性初始的时候均为000,每一天他可以通过努力,让aaa涨111点或bbb涨111点。
为了激励弱弱努力学习,我们共有nnn种奖励,第i种奖励有xix\_ixi,yiy\_iyi,ziz\_izi三种属性,若a≥xia\ge x\_ia≥xi且b≥yib\ge y\_ib≥yi,则弱弱在接下来的每一天都可以得到ziz\_izi的分数。
问m天以后弱弱最多能得到多少分数。
输入:
第一行一个两个整数nnn和mmm(1≤n≤10001\le n\le 10001≤n≤1000,1≤m≤20000000001\le m\le 20000000001≤m≤2000000000)。
接下来nnn行,每行三个整数
xix\_ixi,yiy\_iyi,ziz\_izi(1≤xi,yi≤10000000001\le x\_i,y\_i\le 10000000001≤xi,yi≤1000000000,1≤zi≤10000001\le z\_i \le 10000001≤zi≤1000000)。
输出:
一行一个整数表示答案。
样例输入
2 4
2 1 10
1 2 20
样例输出
50
题意 :有两个属性 a 和 b , 初始值均为 0 ,在每一天你可以让 a 或 b 的值去加 1 ,当你到达某一个临界点时,会得到一些分数,问 m 天后最多能得到多少分?
思路分析 :
若不看数据范围,一个比较好想的 dp 是
代码示例:
using namespace std; #define ll long long const ll maxn = 1e6+5; const ll mod = 1e9+7; const double eps = 1e-9; const double pi = acos(-1.0); const ll inf = 0x3f3f3f3f; typedef pair<ll, ll> P; ll n, m; ll xx[1005], yy[1005]; ll v[1005][1005], dp[1005][1005]; map<P, ll>mp; set<ll>s1, s2; int main() { //freopen("in.txt", "r", stdin); //freopen("out.txt", "w", stdout); cin >> n >> m; ll xi = 1, yj = 1; ll x, y, z; for(ll i = 1; i <= n; i++){ scanf("%lld%lld%lld", &x, &y, &z); if (mp.count(P(x, y)) == 0) mp[P(x, y)] = z; else mp[P(x, y)] += z; if (s1.count(x) == 0) {s1.insert(x); xx[xi++] = x;} if (s2.count(y) == 0) {s2.insert(y); yy[yj++] = y;} } sort(xx+1, xx+xi); sort(yy+1, yy+yj); for(ll i = 1; i < xi; i++){ for(ll j = 1; j < yj; j++){ if (mp.count(P(xx[i], yy[j]))) v[i][j] = v[i-1][j]+v[i][j-1]-v[i-1][j-1]+mp[P(xx[i],yy[j])]; else v[i][j] = v[i-1][j]+v[i][j-1]-v[i-1][j-1]; //prllf("---- %d %d %d %d %d\n", i, j, v[i][j], x[i], y[j]); } } for(ll i = 1; i < xi; i++){ for(ll j = 1; j <yj; j++){ ll x1 = dp[i-1][j]+(xx[i]-xx[i-1]-1)*v[i-1][j]+v[i][j]; ll x2 = dp[i][j-1]+(yy[j]-yy[j-1]-1)*v[i][j-1]+v[i][j]; dp[i][j] = max(x1, x2); //prllf("++++ %d %d %d \n", i, j, dp[i][j]); } } ll ans = 0; for(ll i = 1; i < xi; i++){ for(ll j = 1; j < yj; j++){ ll res = dp[i][j] + (m-xx[i]-yy[j])*v[i][j]; ans = max(ans, res); } } printf("%lld\n", ans); return 0; }