wls 两个属性 a 和 b 的 dp

题目描述:

弱弱有两个属性aaa和bbb,这两个属性初始的时候均为000,每一天他可以通过努力,让aaa涨111点或bbb涨111点。

为了激励弱弱努力学习,我们共有nnn种奖励,第i种奖励有xix\_ixiyiy\_iyiziz\_izi三种属性,若a≥xia\ge x\_iaxib≥yib\ge y\_ibyi,则弱弱在接下来的每一天都可以得到ziz\_izi的分数。

问m天以后弱弱最多能得到多少分数。

输入:

第一行一个两个整数nnn和mmm(1≤n≤10001\le n\le 10001n1000,1≤m≤20000000001\le m\le 20000000001m2000000000)。

接下来nnn行,每行三个整数

xix\_ixiyiy\_iyiziz\_izi1≤xi,yi≤10000000001\le x\_i,y\_i\le 10000000001xi,yi1000000000,1≤zi≤10000001\le z\_i \le 10000001zi1000000)。

输出:

一行一个整数表示答案。

样例输入
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;
}

猜你喜欢

转载自www.cnblogs.com/ccut-ry/p/9440556.html