取数游戏2 (nowcoder.com)

转移方程:

F(i,j)=max(F(i1,j)+a[i]b[n(ji)],F(i,j1)+a[j]b[n(ji)])F(i,j) = max(F(i-1,j) + a[i]*b[n - (j - i)], F(i,j-1) + a[j]*b[n - (j-i)])

状态表示:

F(i,j)表示区间i到j取得的最大值。

边界:

F(i,i)=a[i]b[n]F(i,i) = a[i] * b[n]

目标:

F(1,N)F(1,N)

代码:

void solve() {
    int tt; cin>>tt;
    while(tt--) {
        int n; cin>>n;
        vector<vector<int>> f(n + 1, vector<int>(n + 1));
        vector<int> a(n + 1), b(a);
        for(int i = 1; i <= n; ++i) cin>>a[i];
        for(int i = 1; i <= n; ++i) cin>>b[i];
        for(int i = 1; i <= n; ++i) f[i][i] = a[i] * b[n];
        for(int len = 2; len <= n; ++len) {
            for(int i = 1; i + len - 1 <= n; ++i) {
                int j = i + len - 1;
                f[i][j] = max(f[i][j], f[i+1][j] + a[i] * b[n - len + 1]);
                f[i][j] = max(f[i][j], f[i][j-1] + a[j] * b[n - len + 1]);
            }
        }
        cout<<f[1][n]<<endl;
    }
}
// 将b翻转
void solve() {
    int tt; cin>>tt;
    while(tt--) {
        int n; cin>>n;
        vector<vector<int>> f(n + 1, vector<int>(n + 1));
        vector<int> a(n + 1), b(a);
        for(int i = 1; i <= n; ++i) cin>>a[i];
        for(int i = 1; i <= n; ++i) cin>>b[i];
        reverse(b.begin()+1, b.end());
        // swap(b[0], b[n]);
        // cout<<b[1]<<endl;
        for(int i = 1; i <= n; ++i) f[i][i] = a[i] * b[1];
        for(int len = 2; len <= n; ++len) {
            for(int i = 1; i + len - 1 <= n; ++i) {
                int j = i + len - 1;
                f[i][j] = max(f[i][j], f[i+1][j] + a[i] * b[j - i + 1]);
                f[i][j] = max(f[i][j], f[i][j-1] + a[j] * b[j - i + 1]);
                // cout<<f[i][j]<<" ";
            }
            // puts("");
        }
        cout<<f[1][n]<<endl;
    }
}