题目链接:
来看思路:其实刚开始吧 我是一旦思路都没有感觉和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; }