先抽象出状态dp(i,j),表示前i个数中有j个乘号的最大值。
假设j个乘号中最后一个乘号的位置是第t个数和第t+1个数之间,则若要取最大值,须把第t个数之后的数加在一起再乘上dp(t,j-1),由此得出状态转移方程dp(i,j)=max(dp(t,j-1)*(sum[i]-sum[t])),
sum[x]表示前x数的和,用记忆化搜索求解,解是dp(n,k)
#include <iostream>
using namespace std;
long long d[101][101]={0};
int sum[1001]={0};
int n,t;
long long max(long long x,long long y)
{
if(x>y)
return x;
return y;
}
long long dp(int x,int y)
{
long long &ans=d[x][y];
if(ans)
return ans;
if(y==0)
return sum[x];
ans=-1;
for(int i=1;i<x;i++)
{
if(i>y-1)
ans=max(ans,dp(i,y-1)*(sum[x]-sum[i]));
}
return ans;
}
int main()
{
cin>>n>>t;
int a;
for(int i=1;i<=n;i++)
{
cin>>a;
sum[i]=a;
if(i>1)
sum[i]+=sum[i-1];
}
long long ans=dp(n,t);
cout<<ans;
return 0;
}