ACM-ICPC 2018 焦作赛区网络预赛 B. Mathematical Curse

#题解
题目大意 给你n个数字 m个操作符 基础值k 问在基础值上按照顺序挑选(可以不连续)m个数值和操作符组合操作 最终的结果的最大值是多少
最开始基础值为k 操作一次之后结果成为新的基础值

动态规划 d[i][j]表示第i个操作符最后一个使用的字符在j的前面(包括j)的最大最小值 因为有负数乘除所以最小值也要计算
j从i开始到n为有效状态最后结果在最大值最后一次操作取最大
#AC代码

#include <stdio.h>
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;

const ll LINF = 0x3f3f3f3f3f3f3f3f;
const int MAXN = 1e3 + 10;
ll a[MAXN];
char s[10];
ll mx[10][MAXN], mi[10][MAXN];

int main()
{
#ifdef LOCAL
	freopen("C:/input.txt", "r", stdin);
#endif
	int T;
	cin >> T;
	while (T--)
	{
		memset(mx, -0x3f, sizeof(mx));
		memset(mi, 0x3f, sizeof(mi));
		int n, m, k;
		cin >> n >> m >> k;
		for (int i = 1; i <= n; i++)
			scanf("%lld", &a[i]), mx[0][i] = mi[0][i] = k;
		mx[0][0] = mi[0][0] = k;
		scanf("%s", s + 1);
		int l = strlen(s + 1);
		for (int i = 1; i <= l; i++) //操作
			for (int j = i; j <= n; j++)
			{
				if (s[i] == '+')
				{
					mx[i][j] = max({ mx[i][j - 1], mx[i - 1][j - 1] + a[j] });
					mi[i][j] = min({ mi[i][j - 1], mi[i - 1][j - 1] + a[j] });
				}
				else if (s[i] == '-')
				{
					mx[i][j] = max({ mx[i][j - 1], mx[i - 1][j - 1] - a[j] });
					mi[i][j] = min({ mi[i][j - 1], mi[i - 1][j - 1] - a[j] });
				}
				else if (s[i] == '*')
				{
					mx[i][j] = max({ mx[i][j - 1], mx[i - 1][j - 1] * a[j], mi[i - 1][j - 1] * a[j] });
					mi[i][j] = min({ mi[i][j - 1], mi[i - 1][j - 1] * a[j], mx[i - 1][j - 1] * a[j] });
				}
				else if (s[i] == '/')
				{
					mx[i][j] = max({ mx[i][j - 1], mx[i - 1][j - 1] / a[j], mi[i - 1][j - 1] / a[j] });
					mi[i][j] = min({ mi[i][j - 1], mi[i - 1][j - 1] / a[j], mx[i - 1][j - 1] / a[j] });
				}
			}
		ll ans = -LINF;
		for (int i = 1; i <= n; i++)
			ans = max(ans, mx[l][n]);
		cout << ans << endl;
	}

	return 0;
}

猜你喜欢

转载自blog.csdn.net/CaprYang/article/details/82718595