poj1179 Polygon

来源:互联网 发布:什么图案画数据对比表 编辑:程序博客网 时间:2024/05/01 05:25

题意:

4t -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       2147483647vector<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;}