POJ 1179 Polygon(区间DP)

本文探讨了多边形的简化过程,包括去除边和合并顶点的操作,旨在找到最大可能的组合值。通过使用动态规划和最优子结构策略,实现高效的算法优化。

题意:把一个多边形去掉一边,再把任意相邻打两个点合并成一个点,求最大值,

注意:两个最小的数相乘可以得到最大的数。。。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
#include <cmath>
#include <stack>
#include <map>

using namespace std;
#define LL long long
const LL INF =0x3f3f3f3f3f3f3f3f;
int re[59];
int in[59];
int op[59];
int inop[59];
int n;
LL dp[59][59];
LL dp1[59][59];
LL ss(int k,LL a,LL b)
{
    if(k==1) return a+b;
    else return a*b;
}
int oor()
{
    for(int i=0;i<n;i++) for(int j=0;j<n;j++) dp[i][j] = -INF,dp1[i][j] = INF;
    for(int i=0;i<n;i++) dp[i][i] = re[i],dp1[i][i] = re[i];
   // for(int i=n-1;i>=0;i--) cout<<re[i]<< ' ';cout<<endl;
    for(int l=1;l<n;l++)
    {
        for(int i=n-l-1;i>=0;i--)
        {
            LL tmp = -INF;
            LL tmp1 = INF;
            for(int j=0;j<l;j++)
            {
                tmp = max(tmp,ss(op[i+j],dp[i][i+j],dp[i+j+1][i+l]));
                tmp = max(tmp,ss(op[i+j],dp1[i][i+j],dp[i+j+1][i+l]));
                tmp = max(tmp,ss(op[i+j],dp[i][i+j],dp1[i+j+1][i+l]));
                tmp = max(tmp,ss(op[i+j],dp1[i][i+j],dp1[i+j+1][i+l]));

                tmp1 = min(tmp1,ss(op[i+j],dp[i][i+j],dp[i+j+1][i+l]));
                tmp1 = min(tmp1,ss(op[i+j],dp1[i][i+j],dp[i+j+1][i+l]));
                tmp1 = min(tmp1,ss(op[i+j],dp[i][i+j],dp1[i+j+1][i+l]));
                tmp1 = min(tmp1,ss(op[i+j],dp1[i][i+j],dp1[i+j+1][i+l]));
            }
            dp[i][i+l] = tmp;
            dp1[i][i+l] = tmp1;
            //cout<<tmp<<' ';
        }//cout<<endl;
    }
    return dp[0][n-1];
}
int anscnt[59];
void solve()
{
    int cnt = 0;
    LL ans = -INF;
    for(int i=0;i<n;i++)
    {
        for(int j=0;j<n;j++)
        {
            re[j] = in[(i+j)%n];
            op[j] = inop[(i+j)%n];
        }
        LL k = oor();
        if(ans<k)
        {
            cnt = 0;
            anscnt[cnt++] = i;
            ans = k;
        }else if(ans==k)
        {
            anscnt[cnt++] = i;
        }

    }
    cout<<ans<<endl;
    for(int i=0;i<cnt;i++)
    {
        if(i) printf(" ");
        printf("%d",anscnt[i]+1);
    }printf("\n");
}
int main()
{
    #ifndef ONLINE_JUDGE
    freopen("in.txt","r",stdin);
    #endif
    while(~scanf("%d",&n))
    {
        char ch[9];
        for(int i=0;i<n;i++)
        {
            scanf("%s%d",ch,&in[i]);
            if(ch[0]=='t') inop[i] = 1;
            else inop[i] = 2;
        }

        int tmp = inop[0];
        for(int i=0;i<n;i++) inop[i] = inop[i+1];inop[n-1] = tmp;
        solve();
    }
    return 0;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值