版权声明:那个,最起码帮我加点人气吧,署个名总行吧 https://blog.csdn.net/qq_41670466/article/details/82763581
题意就是给你一个数组,再给你一个字符串,这个字符串保证只有+-*/这四个字符,现在你有一个初始值,当你在数组中选则一个值时,你就要用字符串头部的运算符进行运算,然后这个头部字符向后移一位,问当所有的字符都被使用后最大值是多少?
题目链接:https://nanti.jisuanke.com/t/31711
思路:从题意上理解可以得出:这道题类似于01背包,对于每个房间都有进或者不进的情况,只不过在此基础上又增加一个条件是运算符的不同,那么就可以使用一个二维dp,然鹅,考虑到可能会存在到某个房间时,sum为负值,然后此时的运算符为*或者/,然后这个房间的权值为负,那么此时最小的值就变成了正值,这一点要考虑到,那么dp就变成三维;
代码:
#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e3 + 10;
typedef long long ll;
int a[maxn];
ll dp[maxn][10][2];//dp[i][j][0]表示在第i个房间该第j个运算符时的值(o表示存储的最大值,1表示存储的此时最小值)
char s[maxn];
inline ll cal(ll sum, char b, int c)
{
if (b == '+')
{
return sum + c;
}
else if (b == '-')
{
return sum - c;
}
else if (b == '*')
{
return sum * c;
}
else
{
return sum / c;
}
}
int main()
{
int t;
scanf("%d", &t);
while (t--)
{
int n, m, k;
scanf("%d %d %d", &n, &m, &k);//这里之前用的是cin一直都是wa。。qaq以后再也不用cin输入了
for (int i = 1; i <= n; i++)
{
scanf("%d", &a[i]);
}
scanf("%s", s + 1);
for (int i = 0; i <= n; i++)
dp[i][0][0] = dp[i][0][1] = k;
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= min(i, m); j++)
{
ll a1 = cal(dp[i - 1][j - 1][0], s[j], a[i]);
ll a2 = cal(dp[i - 1][j - 1][1], s[j], a[i]);
dp[i][j][0] = max(a1, a2);
dp[i][j][1] = min(a1, a2);
if (i>j)
{
dp[i][j][0] = max(dp[i - 1][j][0], dp[i][j][0]);
dp[i][j][1] = min(dp[i - 1][j][1], dp[i][j][1]);
}
}
}
printf("%lld\n", dp[n][m][0]);
}
return 0;
}