洛谷 p1063 能量项链 区间和环形动态规划dp

洛谷P1063 能量项链

题目链接

题目要求是求得一个最大的能量值,一个最优解。用动态规划做。

因为这是一个环形的手链,那么情况就比较复杂。但是我们可以复杂问题简单化,把环形的手链剪开,变成链形。比如:一条 2 3 5 10 的环状手链,可以从不同位置剪开,变成四条手链:(考虑首尾特殊情况)

  • 2 3 5 10 2
  • 3 5 10 2 3
  • 5 10 2 3 5
  • 10 2 3 5 10
    其实就是 2 3 5 10 2 3 5 10 从第1、2、3、4位开始往后数5个数。

然后根据动态规划的特点,将大问题转化为小问题,利用子问题的答案结构化地计算大问题的答案。

我们先计算三个数能够汇聚的能量,比如 2 3 5 ,答案显而易见就是 2 * 3 * 5 = 30。

将所有三个数挨在一起能够汇聚出来的能量都算出来了之后,就可以利用三个数的能量计算四个数汇聚的能量,而不必重复计算。

比如 2 3 5 10 。 就有两种可能, 原本的 2 * 3 * 5 + 2 * 5 * 10 和 2 * 3 * 10 + 3 * 5 * 10,保留的那个值。

————
i 表示计算多少个数汇聚的能量。因为这里相当于是将环状的手链,拆分成了四条包含 5 个数的数列,所以 i 的最大值就是 5 ,最后从 保存结果的 f 数组中找到长度为 5 的数列能够汇聚的最大能量就可以了。(2 3 5 10 这个例子)

——————
在做这个题之前,可以先看看 石子合并题目链接非常类似的一个题。

#include <bits/stdc++.h>
using namespace std;

int n;
int a[201];
int f[201][201] = {0};
int ans = 0;

int main(){
 cin>>n;
 int i,j,k;
 for(i=1;i<=n;i++){
    cin>>a[i];
    a[i+n] = a[i];
 } 
 for(i=3;i<=n+1;i++){// 每次计算几个数 
    for(j=1;j<=2*n-i+1;j++){// 从第 j 个数开始 
       for(k=j+1;k<j+i-1;k++){// j k j+i-1  
          int m = f[j][k] + f[k][j+i-1];
          f[j][j+i-1] = max(m+a[j]*a[k]*a[j+i-1],f[j][j+i-1]);
       }
    }
 }
 for(i=1;i<=n;i++){
    ans = max(ans,f[i][i+n]);
 }
 cout<<ans;
 return 0;
} 


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值