问题描述:多边形游戏是一个单人玩的游戏,开始时有一个由n个顶点构成的多边形。每个顶点被赋予一个整数值,每条边被赋予一个运算符“+”或“*”。所有边依次用整数从1到n编号 游戏第1步,将一条边删除 随后n-1步按以下方式操作 (1)选择一条边E以及由E连接着的2个顶点V1和V2 (2)用一个新的顶点取代边E以及由E连接着的2个顶点V1和V2。将由顶点V1和V2的整数值通过边E上的运算得到的结果赋予新顶点 最后,所有边都被删除,游戏结束。游戏的得分就是所剩顶点上的整数值。
如图是一个n=4 的游戏过程:
输入格式
第一行一个整数n
第二行分别是边的符号(t表示+,x表示×),点的数值,交错排列。边是连接输入中相连两个点的边。3 <= N <= 50
输出格式
在第一行,您的程序必须写入输入多边形可以获得的最高分数。在第二行,它必须写出所有边的列表,如果在第一步移除,则可以导致具有该分数的游戏。边缘必须按递增顺序书写,以一个空格分隔。
输入样例:
4
t -7 t 4 x 2 x 5
输出样例:
33
1 2
题解:不难看出区间DP,但是分清楚情况是难点所在,设f[ l ][ r ][ 0 ] 表示从 l 到 r 合并以后顶点数值最大值, f[ l ][ r ][ 1 ] 表示 最小值。
考虑当前符号是 乘号 : 当前区间合并产生顶点的最大值可以来自于两个最大值相乘或者两个最小值相乘(负负得正) , 最小值可以来自于两个最小值相乘或者一个最大值乘一个最小值。
当前符号是 加号: 最大值一定来自于两个最大值相加,最小值来自于两个最小值相加。
所以转移时情况分清楚,区间DP 的大框架没有改变。
由于是环状的,倍长区间。
code:
#include<bits/stdc++.h>
#define FILE "Polygon"
using namespace std;
const int MAXN=400;
int n;
int use[MAXN];
long long f[MAXN][MAXN][2];
int read()
{
char c=getchar(); int num=0,f=1;
for( ; c<'0' || c>'9' ; c=getchar()) if(c=='-') f=-1;
for( ; c>='0' && c<='9' ;c=getchar()) num=num*10+(c-'0');
return num*f;
}
void init