多边形游戏(DP)

  • Post author:
  • Post category:其他



题目描述

“多边形游戏”是一款单人益智游戏。

游戏开始时,给定玩家一个具有 N 个顶点 N 条边(编号 1∼N)的多边形,如图 1 所示,其中 N=4。 每个顶点上写有一个整数,每个边上标有一个运算符 +(加号)或运算符 *(乘号)。

在这里插入图片描述

第一步,玩家选择一条边,将它删除。

接下来在进行 N−1 步,在每一步中,玩家选择一条边,把这条边以及该边连接的两个顶点用一个新的顶点代替,新顶点上的整数值等于删去的两个顶点上的数按照删去的边上标有的符号进行计算得到的结果。

下面是用图 1给出的四边形进行游戏的全过程。

在这里插入图片描述

最终,游戏仅剩一个顶点,顶点上的数值就是玩家的得分,上图玩家得分为 0。

请计算对于给定的 N 边形,玩家最高能获得多少分,以及第一步有哪些策略可以使玩家获得最高得分。


输入描述

输入包含两行,第一行为整数 N。

第二行用来描述多边形所有边上的符号以及所有顶点上的整数,从编号为 1的边开始,边、点、边…按顺序描述。

其中描述顶点即为输入顶点上的整数,描述边即为输入边上的符号,其中加号用 t 表示,乘号用 x 表示。


输出描述

输出包含两行,第一行输出最高分数。

在第二行,将满足得到最高分数的情况下,所有的可以在第一步删除的边的编号从小到大输出,数据之间用空格隔开。


数据范围

3≤N≤50,

数据保证无论玩家如何操作,顶点上的数值均在 [−32768,32767] 之内。


Sample Input

4
t -7 t 4 x 2 x 5


Sample Output

:

33
1 2 


具体代码

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<string.h>
using namespace std;
const int M = 51,inf=32768;
int v[M];
char op[M];
int m[M][M][2];
int n;
int minf;
int maxf;
void minMax(int i,int s,int j)
{
	
	int e[5];
	int a = m[i][s][0];//i-到i+s的最小值
	int b = m[i][s][1];//i到i+s的最大值
	int r = (i + s - 1) % n + 1;
	int c = m[r][j - s][0];//i+s到j的最小值
	int d = m[r][j - s][1];//i+s到j的最大值
	if (op[r] == 't')
	{
		minf = a + c;
		maxf = b + d;
	}
	if (op[r] == 'x')
	{
		e[1] = a * c;
		e[2] = a * d;
		e[3] = b * c;
		e[4] = b * d;
		sort(e + 1, e + 5);
		minf = e[1];
		maxf = e[4];
	}	
}
int polyMax()
{
	for (int j = 1; j <= n; j++)
	{
		for (int i = 1; i <= n; i++)
		{
			if (j == 1)
			{
				m[i][j][0] = v[i];
				m[i][j][1] = v[i];
				//printf("%d %d\n", m[i][j][0], m[i][j][1]);
			}
			else {
				m[i][j][0] = inf;
				m[i][j][1] = -inf;
			}
			for (int s = 1; s <j; s++)
			{
				minMax(i, s, j);
				//if (i == 1 && j == 2)
				//{
					//printf("%d %d\n", minf, maxf);
				//}
				if (m[i][j][0] > minf)
					m[i][j][0]=minf;
				if (m[i][j][1] < maxf)
					m[i][j][1] = maxf;
				//printf("i=%d j=%d %d %d\n",i,j, m[i][j][0], m[i][j][1]);
			}
		}
	}
	int t = m[1][n][1];
	//cout<<t;
	for (int i = 2; i <= n; i++)
		if (t < m[i][n][1])
			t = m[i][n][1];
	return t;
}
int main()
{
	//int n;
	scanf("%d", &n);
	int h = 1;
	getchar();
	for (int i = 1; i <= n; i++)
	{
		if (h % 2 == 1)
		{
			scanf("%c", &op[i]);
			h++;
		}
		if (h % 2 == 0)
		{
			scanf("%d", &v[i]);
			getchar();
			h++;
		}
	}
	int t = polyMax();
	cout <<t<< endl;
	//cout << m[1][n][1];
	for (int i = 1; i <= n; i++)
		if (m[i][n][1] == t)
			cout << i << ' ';
	return 0;
}



版权声明:本文为m0_51562545原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。