poj 1651 Multiplication Puzzle (区间DP)

本文深入探讨了区间DP问题中矩阵连乘的状态转移方程,通过实例展示了如何将问题转化为求解最优路径,并提供了具体的代码实现。重点解释了状态dp[i][j]表示从数组a[i]到a[j]的最大乘积和其计算公式,通过分治思想逐步优化解题过程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

做了几道区间DP的题,发现大都采用矩阵连乘的状态转移方程

也即类似dp[i][j] = best(dp[i][j], dp[i][k]+dp[k][j])的形式

这道题目想了好久都没想明白怎么表示状态

看了别人的才知道,我们用dp[i][j]表示把a[i]~a[j]的数取完对应结果

很容易有dp[i][j] = min(dp[i][j], dp[i][k]+dp[k][j]+a[i]*a[k]*a[j])

这里可能理解起来有些困难,其实这样看我们先取完了a[i]~a[k],再取完a[k]~a[j]

因为最后会剩下边界所以剩余的3个数即为a[i], a[k], a[j]

代码如下:

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define MAXN 110
#define LL long long
using namespace std;

int a[MAXN];
LL dp[MAXN][MAXN];

int main(void) {
    int n;
    while(~scanf("%d", &n)) {
        for(int i=1; i<=n; ++i) {
            scanf("%d", &a[i]);
        }
        memset(dp, 0, sizeof(dp));
        for(int i=n-2; i>0; --i) {
            dp[i][i+2] = a[i]*a[i+1]*a[i+2]*1ll;
            for(int j=i+3; j<=n; ++j) {
                dp[i][j] = min(a[i]*a[i+1]*a[j]*1ll+dp[i+1][j], a[i]*a[j-1]*a[j]*1ll+dp[i][j-1]);
                for(int k=i+2; k<j-1; ++k) {
                    dp[i][j] = min(dp[i][j], a[i]*a[k]*a[j]*1ll+dp[i][k]+dp[k][j]);
                }
            }
        }
        cout << dp[1][n] << endl;
    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值