POJ - 1179

本文介绍了一款名为'多边形游戏'的益智游戏,玩家需在一个具有N个顶点和边的多边形上进行操作,通过删除边并根据边上的运算符计算新顶点的值。文章详细阐述了游戏规则,并给出了一种可能的解决方案,包括计算玩家可以达到的最高得分以及第一步删除哪条边可以获得最高分。输入和输出格式以及数据范围也进行了说明,最后展示了一个AC代码实现。
摘要由CSDN通过智能技术生成

POJ 1179
传送口
“多边形游戏”是一款单人益智游戏。

游戏开始时,给定玩家一个具有N个顶点N条边(编号1-N)的多边形,如图1所示,其中N = 4。

每个顶点上写有一个整数,每个边上标有一个运算符+(加号)或运算符*(乘号)。

在这里插入图片描述

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

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

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

1179_2.jpg

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

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

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

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

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

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

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

数据范围
3≤N≤50,
数据保证无论玩家如何操作,顶点上的数值均在[-32768,32767]之内。

输入样例:
4
t -7 t 4 x 2 x 5
输出样例:
33
1 2
ac代码

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<algorithm>
#include<iostream>
#include<math.h>
#include<string.h>
#define ll long long
using namespace std;
int dplow[105][105];
int dpbig[105][105];
int a[55];
char s[105];
const int inf = 0x3f3f3f;
void maxdp(int l, int k, int r)
{
	if (s[k + 1] == 't')
		dpbig[l][r] = max(dpbig[l][r], dpbig[l][k] + dpbig[k + 1][r]);
	else
		dpbig[l][r] = max(dpbig[l][r],max(dpbig[l][k] * dpbig[k + 1][r], max(dplow[l][k] * dpbig[k + 1][r], 
			max(dpbig[l][k] * dplow[k + 1][r], dplow[l][k] * dplow[k + 1][r]))));
}
void mindp(int l, int k, int r)
{
	if (s[k + 1] == 't')
		dplow[l][r] = min(dplow[l][r], dplow[l][k] + dplow[k + 1][r]);
	else
		dplow[l][r] = min(dplow[l][r], min(dpbig[l][k] * dplow[k + 1][r], 
			min(dplow[l][k] * dpbig[k + 1][r], min(dplow[l][k] * dplow[k + 1][r], dpbig[l][k] * dpbig[k + 1][r]))));
}
int main()
{
	int n;
	scanf("%d", &n);
	memset(dplow, inf, sizeof(dplow));
	memset(dpbig, -inf, sizeof(dpbig));
	char g;
	for (int i = 1; i <= 2 * n; i++)
	{
		if (i % 2 == 1)cin>>g, s[i / 2 + n + 1] = s[i / 2 + 1] = g;
		else scanf("%d", &dplow[i / 2][i / 2]),
		dpbig[i / 2 + n][i / 2 + n] = dpbig[i / 2][i / 2] = dplow[i / 2 + n][i / 2 + n] = dplow[i / 2][i / 2];
	}
	for (int len = 2; len <= n; len++)
	{
		for (int l = 1; l <= 2 * n - len + 1; l++)
		{
			int r = l + len - 1;
			for (int k = l; k < r; k++)
			{
				maxdp(l, k, r);
				mindp(l, k, r);
			}
		}
	}
	int ans = -0x3f3f3f;
	for (int i = 1; i <= n; i++)
	{
		ans = max(ans, dpbig[i][i + n - 1]);
	}
	printf("%d\n", ans);
	int bug = 0;
	for (int i = 1; i <= n; i++)
	{
		if (ans == dpbig[i][i + n - 1])
		{
			if (bug == 0)
				printf("%d", i);
			else
				printf(" %d", i);
			bug++;
		}
	}
	printf("\n");
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值