您的位置:首页 > 编程语言 > Go语言

poj1179 Polygon

2013-06-29 11:06 405 查看
题意:

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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: