P1063 能量项链(区间dp)

题目链接: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会更好。

代码:

扫描二维码关注公众号,回复: 8800017 查看本文章
#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;
}
发布了438 篇原创文章 · 获赞 16 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/qq_41829060/article/details/103772595