题意:给你一个表达式,?表示操作符,?可以取+或-,+号只能为p个,-号只能为m个,求这个表达式的最大值。
题解:dfs找表达式,dp[i][j][2]表示i位置上的用加号或减号为j个的时候的最值。
AC代码:
#include<stdio.h>
#include<string.h>
#include<iostream>
#define inf 10000000
using namespace std;
char a[10005];
int dp[10005][105][2];
int p,m,pos;
void dfs()
{
pos++;
int now1=pos;
if(a[pos]!='(')dp[pos][0][0]=dp[pos][0][1]=a[pos]-'0',pos++;
else dfs();
pos++;
int now2=pos;
if(a[pos]!='(')dp[pos][0][0]=dp[pos][0][1]=a[pos]-'0',pos++;
else dfs();
for(int i=0;i<=min(p,m);i++)
for(int j=0;j<=min(p,m)-i;j++)
{
dp[now1-1][i+j+(p>m)][0]=max(dp[now1-1][i+j+(p>m)][0],dp[now1][i][0]-dp[now2][j][1]);
dp[now1-1][i+j+(p<=m)][0]=max(dp[now1-1][i+j+(p<=m)][0],dp[now1][i][0]+dp[now2][j][0]);
dp[now1-1][i+j+(p>m)][1]=min(dp[now1-1][i+j+(p>m)][1],dp[now1][i][1]-dp[now2][j][0]);
dp[now1-1][i+j+(p<=m)][1]=min(dp[now1-1][i+j+(p<=m)][1],dp[now1][i][1]+dp[now2][j][1]);
}
pos++;
}
int main()
{
for(int i=0;i<10005;i++)
for(int j=0;j<105;j++)
dp[i][j][0]=-inf,dp[i][j][1]=inf;
scanf("%s",a);
int l=strlen(a);
scanf("%d%d",&p,&m);
if(l==1)
{
printf("%d\n",a[0]-'0');
return 0;
}
dfs();
if(pos!=l)while(1);
if(p<=m)printf("%d\n",dp[0][p][0]);
else printf("%d\n",dp[0][m][0]);
}

本文介绍了一种使用动态规划解决特定数学表达式最大值问题的方法。通过DFS深度优先搜索配合DP动态规划技术,针对给定的数学表达式,其中包含可变的操作符(加号和减号),寻求在限定数量的加减号条件下,该表达式能够达到的最大值。
696

被折叠的 条评论
为什么被折叠?



