POJ1179

POJ1179

区间DP
很简单的思考过程,把所有的东西看成一个圆,枚举去掉每一个边的情况。然后每一种都是一条链的区间DP。
l == r : dp[l][r] = num[l];
l != r : dp[l][r] = max(dp[l+1][r],dp[l][r-1]);
但是需要注意的是,这题有一个天坑,就是
负数乘负数可以变成一个大的正数

#include <iostream>  
#include <cstdio>  
#include <cstring>  
#include <cmath>  
#include <algorithm>  
#include <queue>  
#include <vector>  
#include <deque>  
#include <bitset>  
using namespace std;  
#define lowbit(x) x&-x  
#define ll long long  
#define dob double  
#define For(i,s,n) for(ll i = s;i <= n;i++)  
#define mem0(a) memset(a,0,sizeof a)  
#define gcd(a,b) __gcd(a,b)  
const int N = 5e2+600;  
const double eps = 1e-6;  
const ll mod = 1e9+7;  
const int inf = 0x3f3f3f3f;  
int n;  
int num[N],a[N];  
char fac[N];  
int dp1[N][N],dp2[N][N];  
bool vis[N][N] = {false};  
void dfs(int l,int r){  
    if(vis[l][r]) return;  
    vis[l][r] = true;  
    if(l == r) {  
        dp1[l][r] = dp2[l][r] = num[l];  
        return ; 
    }  
    For(k,l,r-1){  
        if(fac[k+1] == 't'){  
            dfs(l,k);dfs(k+1,r);  
		    dp1[l][r] = max(dp1[l][r],dp1[l][k]+dp1[k+1][r]);  
		    dp2[l][r] = min(dp2[l][r],dp2[l][k]+dp2[k+1][r]);  
	    }  
        else{  
            dfs(l,k);dfs(k+1,r);  
  
		    dp1[l][r] = max(dp1[l][r],dp1[l][k]*dp1[k+1][r]);  
		    dp1[l][r] = max(dp1[l][r],dp1[l][k]*dp2[k+1][r]);  
		    dp1[l][r] = max(dp1[l][r],dp2[l][k]*dp1[k+1][r]);  
		    dp1[l][r] = max(dp1[l][r],dp2[l][k]*dp2[k+1][r]);  
  
		    dp2[l][r] = min(dp2[l][r],dp1[l][k]*dp1[k+1][r]);  
		    dp2[l][r] = min(dp2[l][r],dp1[l][k]*dp2[k+1][r]);  
		    dp2[l][r] = min(dp2[l][r],dp2[l][k]*dp1[k+1][r]);  
		    dp2[l][r] = min(dp2[l][r],dp2[l][k]*dp2[k+1][r]);  
		}  
    }  
    return ;  
}  
int main() {  
    ios::sync_with_stdio(false);  
    cout.tie(NULL);  
	cin>>n;  
    For(i,1,2*n)  
        For(j,1,2*n)  
        dp1[i][j] = -inf,dp2[i][j] = inf;  
    For(i,1,n) {  
        cin>>fac[i]>>num[i];  
        num[i+n] = num[i],fac[i+n] = fac[i];  
    }  
    int ans = -inf;  
    For(i,1,n){  
        dfs(i,i+n-1);  
        ans = max(ans,dp1[i][i+n-1]);  
    }  
    cout<<ans<<endl;  
    int ok = 0;  
    For(i,1,n){  
        if(ans == dp1[i][i+n-1]){  
            if(ok) cout<<' ';  
		    cout<<i;  
		    ok = 1;  
		 }  
    }  
    return 0;  
}
posted @ 2021-02-16 20:09  Paranoid5  阅读(27)  评论(0编辑  收藏  举报