Rise in Price - hdu6981

首先容易想到的是每一格都是由上或左转移而来,并且经过格子必将钻石取完。dp的话空间不够,所以思考其他方法。
由于每格转移到本格都是增加本格的数量和价值,所以我们只需要考虑到本格之前的最佳状态即可。
因为状态由两部分组成-价值和数量,价值乘数量大的肯定优。所以我们存下所有可能的状态,从其中挑选最优的一些解转移。所有的状态有 C 2 n n C_{2n}^n C2nn个,经过优化只有几千个状态有可能~~(出题人说的,我还是没法严谨的推出来结果)~~ 。

#include "bits/stdc++.h"
#define int long long
using namespace std;
int a[200][200];
int b[200][200];
vector<pair<int, int>> p[200][200];

signed main() {
    
    
    int T;
    cin >> T;
    while (T--) {
    
    
        int n;
        cin >> n;
        for (int i = 1; i <= n; ++i) {
    
    
            for (int j = 1; j <= n; ++j) {
    
    
                cin >> a[i][j];
                p[i][j].clear();
            }
        }
        for (int i = 1; i <= n; ++i) {
    
    
            for (int j = 1; j <= n; ++j) {
    
    
                cin >> b[i][j];
            }
        }
        for (int i = 1; i <= n; ++i) {
    
    
            for (int j = 1; j <= n; ++j) {
    
    
                if (i == 1 && j == 1) {
    
    
                    p[i][j].push_back({
    
    a[i][j], b[i][j]});
                    continue;
                }
                else if (i == 1) p[i][j].push_back(p[i][j - 1][0]);
                else if (j == 1) p[i][j].push_back(p[i - 1][j][0]);
                else {
    
    
                    int p1 = 0, p2 = 0;
                    while (p[i][j].size() < 100) {
    
    
                        if (p1 < p[i][j-1].size() && p2 < p[i-1][j].size()) {
    
    
                            if (p[i][j - 1][p1].first * p[i][j - 1][p1].second >
                                p[i - 1][j][p2].first * p[i - 1][j][p2].second) {
    
    
                                p[i][j].push_back(p[i][j - 1][p1]);
                                p1++;
                            } else {
    
    
                                p[i][j].push_back(p[i - 1][j][p2]);
                                p2++;
                            }
                        } else if (p1 < p[i][j-1].size()){
    
    
                            p[i][j].push_back(p[i][j - 1][p1]);
                            p1++;
                        } else if (p2 < p[i-1][j].size())
                        {
    
    
                            p[i][j].push_back(p[i - 1][j][p2]);
                            p2++;
                        } else break;
                    }

                }
                for (int k = 0; k < p[i][j].size(); ++k) {
    
    
                    p[i][j][k].first += a[i][j];
                    p[i][j][k].second += b[i][j];
                }
                sort(p[i][j].begin(), p[i][j].end(), [&](pair<int, int> tmp1, pair<int, int> tmp2) {
    
    
                    return tmp1.first * tmp1.second > tmp2.first * tmp2.second;
                });
            }
        }
        cout << p[n][n][0].first * p[n][n][0].second << endl;


    }
}

猜你喜欢

转载自blog.csdn.net/weixin_45509601/article/details/119185109