poj1179 Polygon

题意:

4
t -7 t 4 x 2 x 5
t代表加号,x代表乘号

首先去掉一个加法或者乘法

然后每次取两个相邻的数相加或相乘

注意-7可以与5相加

求解出的最大值

解法:

很容易想到区间DP

这里要注意的是

区间的最大值可能由两个子区间的最小值相乘得到

所以除了最大值还要保存最小值

#include<cstdio>
#include<algorithm>
#include<vector>
#include<iostream>
using namespace std;
#define INT_MIN     (-2147483647 - 1) 
#define INT_MAX       2147483647
vector<int>ans;
int high;
int n;
char e[60];
int v[60];
int opt_max[60][60];//opt[i][j]表示v[i]......v[j]能组成的最大值
int opt_min[60][60];//opt[i][j]表示v[i]......v[j]能组成的最小值
void dp(int i,int j)//计算opt[i][j]
{
	if(i==j)
	{
		opt_max[i][j]=v[i];
		opt_min[i][j]=v[i];
		return;
	}
	for(int k=i;k!=j;k=(k+1)%n)//opt[i][k],opt[(k+1)%n][j]
	{
		if(opt_max[i][k]==INT_MIN)
		{
			dp(i,k);
		}
		if(opt_max[(k+1)%n][j]==INT_MIN)
		{
			dp((k+1)%n,j);
		}
		if(e[(k+1)%n]=='t')
		{
			opt_max[i][j]=max(opt_max[i][j],opt_max[i][k]+opt_max[(k+1)%n][j]);//最大值可由部分的最大值相加得到
			opt_min[i][j]=min(opt_min[i][j],opt_min[i][k]+opt_min[(k+1)%n][j]);//最小值可由部分的最小值相加得到
		}
		if(e[(k+1)%n]=='x')
		{
			opt_max[i][j]=max(opt_max[i][j],opt_max[i][k]*opt_max[(k+1)%n][j]);//最大值可由部分的最大值相乘得到
			opt_max[i][j]=max(opt_max[i][j],opt_min[i][k]*opt_min[(k+1)%n][j]);//最大值可由部分的最小值相乘得到
			opt_max[i][j]=max(opt_max[i][j],opt_max[i][k]*opt_min[(k+1)%n][j]);
			opt_max[i][j]=max(opt_max[i][j],opt_min[i][k]*opt_max[(k+1)%n][j]);

			opt_min[i][j]=min(opt_min[i][j],opt_max[i][k]*opt_max[(k+1)%n][j]);
			opt_min[i][j]=min(opt_min[i][j],opt_min[i][k]*opt_min[(k+1)%n][j]);
			opt_min[i][j]=min(opt_min[i][j],opt_max[i][k]*opt_min[(k+1)%n][j]);
			opt_min[i][j]=min(opt_min[i][j],opt_min[i][k]*opt_max[(k+1)%n][j]);
		}
	}
}
int main()
{
	//freopen("in.txt","r",stdin);
	while(~scanf("%d",&n))
	{
		getchar();
		high=INT_MIN;
		ans.clear();
		for(int i=0;i<n;i++)
		{
			cin>>e[i];
			scanf("%d",&v[i]);//v[i%n]与v[(i+1)%n]之间的边为e[(i+1)%n]
		}
		for(int i=0;i<n;i++)
		{
			for(int j=0;j<n;j++)
			{
				opt_max[i][j]=INT_MIN;
				opt_min[i][j]=INT_MAX;
			}
		}
		for(int i=0;i<n;i++)//舍弃e[i],相应的两个点位v[i],v[(i-1+n)%n]
		{
			if(opt_max[i][(i-1+n)%n]==INT_MIN)
			{
				dp(i,(i-1+n)%n);
			}
			if(high==INT_MIN)
			{
				ans.push_back(i+1);
				high=opt_max[i][(i-1+n)%n];
				continue;
			}
			if(opt_max[i][(i-1+n)%n]==high)
			{
				ans.push_back(i+1);
				continue;
			}
			if(opt_max[i][(i-1+n)%n]>high)
			{
				ans.clear();
				ans.push_back(i+1);
				high=opt_max[i][(i-1+n)%n];
			}
		}
		printf("%d\n",high);
		for(int i=0;i<ans.size()-1;i++)
		{
			printf("%d ",ans[i]);
		}
		printf("%d\n",ans.back());
	}
	return 0;
}


你可能感兴趣的:(poj1179 Polygon)