题目链接:

来看思路:其实刚开始吧 我是一旦思路都没有感觉和DP一点关系都没有  后来看了大神的代码才明白怎么回事

我们先设dp[i][j] 为0到i中间插入j个称号的最大值 a[i][j]表示从第i位到j位的整数值

我们可以让乘号放在不同的位置来寻找哪个才是最大值   所以可得状态转移方程:

dp[i][j] = max(dp[i][j],dp[k][j] * a[k + 1][i]);  k为乘号的位置

下面看代码:

#include<stdio.h>
#include<math.h>
#include<algorithm>
#include<string.h>
#include<iostream>

using namespace std;

long long dp[22][22];
long long a[22][22];
char str[22];

int main()

{
    int l,T,m,i,j,k;
    scanf("%d",&T);
    while(T--)
    {

        scanf("%s%d",str,&m);
        l = strlen(str);
        m--;
        memset (a, 0, sizeof(a));
        memset (dp, 0, sizeof(dp));
        for(i = 0;i < l;i++)
        {
            a[i][i] = str[i] - '0';
            for(j = i + 1;j < l;j++)
            {
                a[i][j] = a[i][j - 1] * 10 + str[j] - '0';
            }
        }
        for(i = 0;i < l;i++)
        {
            dp[i][0] = a[0][i];
        }
        for(j = 1;j <= m;j++)
        {
            for(i = j;i < l;i++)
            {
                for(k = 0;k < i;k++)
                {
                    dp[i][j] = max(dp[i][j],dp[k][j - 1] * a[k + 1][i]);
                }
            }
        }
        printf("%lld\n",dp[l - 1][m]);
    }
    return 0;
}