【区间dp】P4342 [IOI1998]Polygon

本文深入讲解了一种基于区间动态规划的算法实现,通过延长输入序列并进行预处理,解决了涉及区间乘积最大值和最小值的问题。代码示例展示了如何在特定条件下更新状态矩阵,以找到最优解。

这道题目第一步划分时,可以直接将其延长一倍,然后就直接进行操作,剩下的就是普通的区间dp了

由于dp的内容有乘积,有可能是两个负数的最小值乘来,所以需要维护一个最小值

 

 

代码

#include<bits/stdc++.h>
using namespace std;
const int inf=0x3f3f3f3f;
int n,ans=-inf;
int a[105];
int f[150][150],g[150][150];
char c[105];
int main(){
	freopen("a.in","r",stdin); 
    scanf("%d\n",&n);
    for(int i=1;i<=n;i++)
        scanf("%c %d",&c[i],&a[i]),getchar(),a[n+i]=a[i],c[n+i]=c[i];
    for(int i=1;i<=(n<<1);i++)
        for(int j=1;j<=(n<<1);j++)
            f[i][j]=-inf,g[i][j]=inf;

    for(int i=1;i<=(n<<1);i++)
		f[i][i]=g[i][i]=a[i];
    for(int len=2;len<=n;len++)
        for(int i=1,j=len;j<=(n<<1);i++,j++)
            for(int k=i;k<j;k++)
			{
                if(c[k+1]=='x')
				{
                    f[i][j]=max(f[i][j],max(f[i][k]*f[k+1][j],max(g[i][k]*g[k+1][j],max(f[i][k]*g[k+1][j],g[i][k]*f[k+1][j]))));
                    g[i][j]=min(g[i][j],min(f[i][k]*f[k+1][j],min(g[i][k]*g[k+1][j],min(f[i][k]*g[k+1][j],g[i][k]*f[k+1][j]))));
                }
                else if(c[k+1]=='t')
				{
                    f[i][j]=max(f[i][j],f[i][k]+f[k+1][j]);
                    g[i][j]=min(g[i][j],g[i][k]+g[k+1][j]);
                }
            }
    for(int i=1;i<=n;i++)
		ans=max(ans,f[i][i+n-1]);
			printf("%d\n",ans);
    for(int i=1;i<=n;i++)
		if(f[i][i+n-1]==ans)
			printf("%d ",i);
    return 0;
}

 

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值