| |||
来源 | POJ | ||
描述 | |||
多边形游戏是一种在一个具有n个顶点的多边形上进行的游戏。如图1是一个n=4对应多边形,每个顶点上都有一个整数,每条边都有一个运算符+或者*,所有边按从1到n进行编号。 游戏都首先移除一条边,接下来可以进行如下操作:选择一条边E和与之相关联的点V1和V2,用一个新的点替换它们,新点上的整数为V1,V2上的整数用E上的操作符运算后的结果。 没有边时游戏结束,游戏得分就是最后剩下的那个顶点上的整数。 对于图1中的多边形,如果游戏者首先去掉3,然后依次去掉1、4、2,最后得分将是0。 请你写一个程序,对于给定的多边形,计算出可能得到的最高分,并列出第一步移除哪些边可以得到这个最高分。 | |||
关于输入 | |||
输入第一行是一个正整数n(3<=n<=50),表示多边形的边数。 接下来一行是这个多边形的描述,包含n条边和n个顶点,加号边用t表示,乘号边用x表示,顶点用顶点上标的整数表示,输入按照边的编号从1到n的顺序给出。 | |||
关于输出 | |||
第一行输出可能得到的最高分。 第二行输出一些边的列表,只有第一步移除的边在这个列表中才可能得到最高分。每条边都用这个边上的编号表示,列表必须是升序的。 | |||
例子输入 | |||
4
t -7 t 4 x 2 x 5 | |||
例子输出 | |||
33
1 2 |
思路:
1、对每种第一次去掉的边进行打表
2、由于负负得正,所以你不能只算最大值。也就是说要计算多边形上连续的一段所能达到的最小值和最大值.
代码:
#include<iostream>
using namespace std;
int main()
{
int n;
char ope[50],tope[50];
int num[50],tnum[50];
int maxresult[50][50][50];
int minresult[50][50][50];
int i,j,k,l;
int temp1,temp2;
int min,max;
int choice[50];
cin>>n;
for(i=0;i<2*n;i++)
{
if(i%2 == 0)
cin>>ope[i/2];
else
cin>>num[(i-1)/2];
}
memset(maxresult,-999999,sizeof(maxresult));
memset(minresult,999999,sizeof(minresult));
for(i=0;i<n;i++)
{
for(j=0;j<n;j++)
{
tope[j]=ope[(i+1+j)%n];
tnum[j]=num[(i+j)%n];
}
for(j=0;j<n;j++)
{
maxresult[i][j][j]=tnum[j];
minresult[i][j][j]=tnum[j];
}
for(j=1;j<=n-1;j
{
for(k=0;k+j<=n-1;k++)
{
for(l=k;l<k+j;l++)
{
if(tope[l] == 't')
temp1 = maxresult[i][k][l]+maxresult[i][l+1][k+j];
temp2 = minresult[i][k][l]+minresult[i][l+1][k+j];
}
else
{
temp1 = maxresult[i][k][l]*maxresult[i][l+1][k+j];
temp2 = minresult[i][k][l]*minresult[i][l+1][k+j];
}
if(temp1>maxresult[i][k][k+j])
maxresult[i][k][k+j]=temp1;
if(temp2>maxresult[i][k][k+j])
maxresult[i][k][k+j]=temp2;
if(temp1<minresult[i][k][k+j])
minresult[i][k][k+j]=temp1;
if(temp2<minresult[i][k][k+j])
minresult[i][k][k+j]=temp2;
}
}
}
}
max=-999999;
j=0;
for(i=0;i<n;i++)
{
if(maxresult[i][0][n-1] > max)
{
max=maxresult[i][0][n-1];
j=0;
choice[j++]=i+1;
}
else if(maxresult[i][0][n-1]==max)
choice[j++]=i+1;
}
cout<<max<<endl;
k=j;
for(j=0;j<k-1;j++)
cout<<choice[j]<<" ";
cout<<choice[k-1]<<endl;
return 0;
}