题目链接:https://www.luogu.com.cn/problem/P1063
思路:
一开始想直接找到最大的位置,然后以从那个点作为起点,然后枚举区间长度进行更新就好了。
代码:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 220;
ll dp[N][N] = {0},a[N],b[N];
int main(void)
{
int n;scanf("%d",&n);
ll mx = 0;int pos = 1;
for(int i=1;i<=n;i++)
{
scanf("%lld",&a[i]);
if(i == 1){ pos = i; mx = a[i]; }
else{
if(mx < a[i])
{
pos = i;mx = a[i];
}
}
}
for(int i=pos,j=1;j<=n;j++,i++)
{
if(i == n+1) i = 1;
b[j] = a[i];
}
for(int i=1;i<=n;i++) a[i] = b[i];//printf("ai = %lld\n",a[i]);
a[n+1] = a[1];
for(int i=2;i<=n;i++)
{
for(int l=1;l+i-1<=n;l++)
{
int r = l+i-1;
for(int j=l+1;j<=r;j++)
dp[l][r] = max(dp[l][r],dp[l][j-1] + dp[j][r] + a[l]*a[j]*a[r+1]);
}
}
printf("%lld\n",dp[1][n]);
return 0;
}
思路:
看了别人的题解发现直接将长度开到2×n会更好。
代码:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 220;
ll dp[N][N] = {0},a[N];
int main(void)
{
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++) scanf("%lld",&a[i]),a[n+i] = a[i];
a[2*n+1] = a[1];
for(int i=2;i<=n;i++)
{
for(int l=1;l+i-1<=n*2;l++)
{
int r = l+i-1;
for(int j=l+1;j<=r;j++)
dp[l][r] = max(dp[l][r],dp[l][j-1] + dp[j][r] + a[l]*a[j]*a[r+1]);
}
}
ll ans = 0;
for(int i=1;i<=n;i++) ans = max(ans,dp[i][i+n-1]);
printf("%lld\n",ans);
return 0;
}