求助区间 dp
查看原帖
求助区间 dp
574944
Micnation_AFO楼主2023/3/26 10:30

rt,有强迫症,放在我主页的任务计划里,那个鲜明的“0“看着我好难受/fn。

如果有好心人看出来哪儿错了吗麻烦说详细一点,因为退役很久了所以启发式的点拨不一定能看得出来,提前/bx

#include <iostream>
#include <cstring>

using namespace std;

const int N = 55;

int n;
int a[N * 2];
char op[N * 2];
int f_max[N][N], f_min[N][N];

int read() {
    int x = 0, f = 1;
    char ch = getchar();
    while (ch < '0' || ch > '9') { f = (ch == '-' ? -1 : f); ch = getchar(); }
    while (ch >= '0' && ch <= '9') { x = x * 10 + ch - '0'; ch = getchar(); }
    return x * f;
}

char getch() {
    char ch = getchar();
    while (ch == ' ' || ch == '\n' || ch == '\r') ch = getchar();
    return ch;
}

int main() {
    cin >> n;
    string s = "";
    for (int i = 1; i <= n; i++) {
        char ch = getch();
        a[i] = read();
        s.push_back(ch);
    }
    for (int i = 1; i <= n; i++) op[i] =  (s[i - 1] == 't' ? '+' : '*');
    for (int i = n + 1; i <= 2 * n; i++) op[i] =  (s[i - n - 1] == 't' ? '+' : '*'), a[i] = a[i - n];
    n *= 2;
    memset(f_max, -127, sizeof(f_max));
    memset(f_min, 127, sizeof(f_min));
    a[0] = a[n];
    for (int i = n; i >= 1; i--) a[i] = a[i - 1]; 
    //for (int i = 1; i <= n; i++) cout << a[i] << " ";
    for (int i = 1; i <= n; i++) f_max[i][i] = f_min[i][i] = a[i];
    for (int len = 2; len <= n; len++) {
        for (int l = 1; l + len - 1 <= n; l++) {
            int r = l + len - 1;
            for (int k = l; k < r; k++) {
                if (op[k] == '*') {
                    f_max[l][r] = max(f_max[l][r], f_min[l][k] * f_min[k + 1][r]);
                    f_max[l][r] = max(f_max[l][r], f_max[l][k] * f_max[k + 1][r]);
                    f_max[l][r] = max(f_max[l][r], f_max[l][k] * f_min[k + 1][r]);
                    f_max[l][r] = max(f_max[l][r], f_min[l][k] * f_max[k + 1][r]);
                    f_min[l][r] = min(f_min[l][r], f_min[l][k] * f_min[k + 1][r]);
                    f_min[l][r] = min(f_min[l][r], f_min[l][k] * f_max[k + 1][r]);
                    f_min[l][r] = min(f_min[l][r], f_min[l][k] * f_max[k + 1][r]);
                    f_min[l][r] = min(f_min[l][r], f_max[l][k] * f_min[k + 1][r]);
                }
                else {
                    f_max[l][r] = max(f_max[l][k] + f_max[k + 1][r], f_min[l][k] + f_min[k + 1][r]);
                    f_max[l][r] = max(f_max[l][r], f_max[l][k] + f_min[k + 1][r]);
                    f_max[l][r] = max(f_max[l][r], f_min[l][k] + f_max[k + 1][r]);
                    f_min[l][r] = min(f_min[l][k] + f_min[k + 1][r], f_min[l][k] + f_max[k + 1][r]);
                    f_min[l][r] = min(f_min[l][r], f_min[l][k] + f_max[k + 1][r]);
                    f_min[l][r] = min(f_min[l][r], f_max[l][k] + f_min[k + 1][r]);
                }
                /*
                f_max[l][r] = max(f_max[l][k] + f_max[k + 1][r], f_max[l][k] * f_max[k + 1][r]);
                f_max[l][r] = max(f_max[l][r], f_min[l][k] * f_min[k + 1][r]);
                f_min[l][r] = min(f_min[l][k] + f_min[k + 1][r], f_min[l][k] * f_max[k + 1][r]);
                f_min[l][r] = min(f_min[l][r], f_max[l][k] * f_min[k + 1][r]);
                */
            }
        }
    }
    int ans = -1e9; n /= 2;
    for (int i = 1; i <= n; i++) ans = max(ans, f_max[i][i + n - 1]);
    cout << ans << endl;
    for (int i = 2; i <= n + 1; i++)
        if (f_max[i][i + n - 1] == ans) cout << i - 1 << " ";
    /*
    cout << endl;
    for (int i = 1; i <= n; i++)
        cout << f_max[i][i + n - 1] << " ";
    cout << endl;
    cout << f_max[2][4] << endl;
    */
    return 0;
}
2023/3/26 10:30
加载中...