递归——多边形游戏(递归法)

描述
    一个多边形,开始有n个顶点。每个顶点被赋予一个正整数值,每条边被赋予一个运算符“+”或“*”。所有边依次用整数从1到n编号。
    现在来玩一个游戏,该游戏共有n步:
    第1步,选择一条边,将其删除
    随后n-1步,每一步都按以下方式操作:(1)选择一条边E以及由E连接着的2个顶点v1和v2; (2)用一个新的顶点取代边E以及由E连接着的2个顶点v1和v2,将顶点v1和v2的整数值通过边E上的运算得到的结果值赋给新顶点。

    最后,所有边都被删除,只剩一个顶点,游戏结束。游戏得分就是所剩顶点上的整数值。那么这个整数值最大为多少?
关于输入
第一行为多边形的顶点数n(n≤20),其后有n行,每行为一个整数和一个字符,整数为顶点上的正整数值,字符为该顶点到下一个顶点间连边上的运算符“+”或“*”(最后一个字符为最后一个顶点到第一个顶点间连边上的运算符)。
关于输出
输出仅一个整数,即游戏所计算出的最大值。
例子输入
4

4 *

5 +

5 +

3 +

例子输出
70

提示
小规模问题可不必用动态规划方法编程求解,仅用递归就可以求解。
计算中不必考虑计算结果超出整数表达范围的问题,给出的数据能保证计算结果的有效性。
在给的例子中,计算过程为(3+4)*(5+5)=70。

如何用线性的数组创造出如题的闭合多边形,并可不断删减数,存储新数?

①首先将首尾链接:可通过if判断从尾部索引跳回头部索引

②每次计算(如第i位与第i+k位计算)

        1.所用数据为:i位的数值,i位的运算符,i+k位的数值

        2.运算结束后:将i位的数值与运算符标记,而i+k位不标记

                                同时,将运算结果覆盖i+k位的数值,

即可够成循环并能采用递归计算。

#include<iostream>
#include<cstring>
#include<cmath>
using namespace std;
int MAX = 0;
struct intx
{
	int d;
	bool x;
};
struct charx
{
	char c;
	bool y;
};
intx a[20] = {};
charx b[20];
int n;
void f(int N)//还剩下点的个数
{
	if (N == 1) {//只剩下一个点了
		for (int i = 0; i < n; ++i) {
			if (a[i].x == 0) {//找到哪个位置存储着最终结果
				MAX = max(a[i].d, MAX);//比较大小
				return;
			}
		}
	}
	for (int i = 0; i < n; ++i) {//依次尝试每个点作为起始
		if (a[i].x == 0) {//该点可以处理,进行运算
			int temp = 0;
			for (int j = i + 1;; ++j) {
				if (j == n) {//要构成循环!让它比合起来
					j = 0;
				}
				if (a[j].x == 1)	continue;//已经算过了,跳过
				else {
					if (b[i].c == '+') { temp = a[i].d + a[j].d; }
					else { temp = a[i].d * a[j].d; }
					a[i].x = 1;//标记为处理过
					int t = a[j].d;
					a[j].d = temp;//将运算结果储存在靠后的这个位置里
					f(N - 1);//进行下一次函数调用
					a[i].x = 0;//回溯
					a[j].d = t;//回溯
					break;
				}
			}
		}
	}
}
int main()
{
	cin >> n;
	for (int i = 0; i < n; ++i) {
		cin >> a[i].d >> b[i].c;
		a[i].x = 0;
		b[i].y = 0;
	}
	f(n);
	cout << MAX << endl;
	return 0;
}

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值