ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

洛谷P4342 [IOI1998]Polygon

2022-04-14 14:01:09  阅读:177  来源: 互联网

标签:200 洛谷 Polygon int P4342 DP inf include dp


题目

https://www.luogu.com.cn/problem/P4342
我会做IOI题辣

思路

算法设计与分析的课堂例题。

首先这是一个环状DP,那么根据老套路,破环成链。发现要求的东西也很相关,就是求环从哪里断开可取到最优解,然后我们就可以很自信地接着往下做了。

考虑链的情况,是一个很裸的区间DP的形式。对区间[j,i],枚举中断点k,根据符号合并左右两段的结果即可。

比较坑的一点就是乘法。可以发现负数对乘法造成了很坏的影响,不能直接用最大值乘最大值。但是必然是极值乘极值。

于是可以同时维护一个区间的最小DP值和最大DP值,把4种组合方式都查一遍就得到正确的解了。

因为情况比较多,所以转移方程不好写,不过看代码应该就明白了。

代码

点击查看代码
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#define inf 0x3f3f3f3f
using namespace std;
int num[200],op[200];
int dp[2][200][200];//dp[0][i][j]表示i~j区间得到的最小值,dp[1][i][j]表示最大值
int main(){
    int i,j,n,m,k;
    int x;
    int ans=-inf;
    char s[10];
    scanf("%d",&n);
    for(i=1;i<=2*n;++i){
        if(i&1){
            scanf("%s",s);
            if(s[0]=='t') op[(i+1)/2]=1;
            else op[(i+1)/2]=2;
        }
        else{
            scanf("%d",&x);
            num[i/2]=x;
        }
    }
    for(i=n+1;i<=2*n;++i) num[i]=num[i-n];
    for(i=n+1;i<=2*n;++i) op[i]=op[i-n];
    for(i=1;i<=2*n;++i){
        dp[1][i][i]=dp[0][i][i]=num[i];
        for(j=i-1;j>=i-n+1&&j>=1;--j){
            dp[1][j][i]=-inf;dp[0][j][i]=inf;
            for(k=j;k<i;++k){
                if(op[k+1]==1){
                    dp[1][j][i]=max(dp[1][j][i],dp[1][j][k]+dp[1][k+1][i]);
                    dp[0][j][i]=min(dp[0][j][i],dp[0][j][k]+dp[0][k+1][i]);
                }
                else{
                    dp[1][j][i]=max(dp[1][j][i],dp[1][j][k]*dp[1][k+1][i]);
                    dp[1][j][i]=max(dp[1][j][i],dp[1][j][k]*dp[0][k+1][i]);
                    dp[1][j][i]=max(dp[1][j][i],dp[0][j][k]*dp[1][k+1][i]);
                    dp[1][j][i]=max(dp[1][j][i],dp[0][j][k]*dp[0][k+1][i]);
                    dp[0][j][i]=min(dp[0][j][i],dp[0][j][k]*dp[0][k+1][i]);
                    dp[0][j][i]=min(dp[0][j][i],dp[1][j][k]*dp[0][k+1][i]);
                    dp[0][j][i]=min(dp[0][j][i],dp[0][j][k]*dp[1][k+1][i]);
                    dp[0][j][i]=min(dp[0][j][i],dp[1][j][k]*dp[1][k+1][i]);
                }
            }
        }
    }
    for(i=1;i<=n;++i){
        ans=max(ans,dp[1][i][i+n-1]);
    }
    printf("%d\n",ans);
    for(i=1;i<=n;++i){
        if(dp[1][i][i+n-1]==ans) printf("%d ",i);
    }
    // system("pause");
    return 0;
}

标签:200,洛谷,Polygon,int,P4342,DP,inf,include,dp
来源: https://www.cnblogs.com/landmine-sweeper/p/16144193.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有