JSK-107305丨ICPC Jiaozuo Station Network Tour B丨dp

题意: Given n numbers, m numbers are sequentially taken, and the operations are sequentially performed on k according to the given m operators. Make sure that all m operators are used and calculate the maximum value of the calculation result. Idea: Observed that m is very small, only 5,5x1000 complexity is enough, so you can find the state transition equation and derive the relationship. Let us remember that dp[i][j] takes the ith number and uses the maximum value of the jth operator. It is easy to think of two kinds of results, One is: dp[i][j]= dp[i-1][j-1]~ operator [j]~a[i]; that is, the current ai case; The other is: dp[i][j]= dp[i][j-1]; that is, if you do not take ai, transfer the last use of j operators;

at first I thought These two are enough, and wa has three rounds. Share an easy-to-follow example: 1 5 3 6 -5 3 -4 -1 2 *+/ In this example, we need ((6*-5)+-4)/-1 to get the biggest answer, but we can see that this maximum is transferred from the middle minimum (the case of the minimum /-1), then I remembered a pd, used a similar method to find the minimum value, and then transferred the maximum value obtained by the minimum value to dp, and the result is complete. Sure enough, I can't think too simple, look at the code. Initialize some small details and think about it.


#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
typedef long long ll;
const ll mod=1e9+7;
ll calc(ll x,char op,ll y)
{
    switch(op){
        case '+':
            return x+y;
        case '-':
            return x-y;
        case '*':
            return x*y;
        case '/':
            return x/y;
    }
}
int T,n,m;
ll k;
ll a[1005],dp[1005][6],pd[1005][6];
char f[15];
int main()
{
    scanf("%d",&T);
    while(T--)
    {
        memset(dp,0x80,sizeof(dp));
        memset(pd,0x3f,sizeof(pd));
        scanf("%d %d %lld",&n,&m,&k);
        for(int i=1;i<=n;i++)
            scanf("%lld",a+i);
        scanf("%s",f+1);

        for(int i=0;i<=n;i++)
            pd[i][0]=dp[i][0]=k;
        for(int i=1;i<=n;i++)
            for(int j=1;j<=m;j++){
                if(i<=m&&j>i)break;
                dp[i][j]=max(dp[i-1][j],calc(dp[i-1][j-1],f[j],a[i]));
                pd[i][j]=min(pd[i-1][j],calc(pd[i-1][j-1],f[j],a[i]));
                dp[i][j]=max(dp[i][j],calc(pd[i-1][j-1],f[j],a[i]));
                pd[i][j]=min(pd[i][j],calc(dp[i-1][j-1],f[j],a[i]));
            }

        printf("%lld\n",dp[n][m]);
    }
    return 0;
}

/*
5
5 5 6
-1 -1 -1 -1 -1
-----
2 1 5
2 3
/
3 2 1
1 2 3
++
4 4 5
1 2 3 4
+-*/