#POJ 1651 Multiplication Puzzle

Multiplication Puzzle

题意&分析:
给定一个数列,出去第一个和最后一个数,中间的数都可以取,再左边和右边各取一个数,三者相乘,即m[ i ]* m[ k ] * m [ j ] (1 <= i < k < j <= n ) ; 求最小的和。

这道题类似矩阵连乘的问题(传送门)。

这里写图片描述

dp[ i ][ j ] 的含义是在区间[ i - 1, j ] 的区间内最小的乘法和。这里和一般的区间dp模板稍有区别,不过写法很随意,都可以。

代码如下:

#define INF 0x3f3f3f3f
#define TEST cout<<"stop here"<<endl 
using namespace std;
typedef long long ll;
const ll mod = 1e9 + 7;


int dp[110][110];
int a[110];
int main(){
    std::ios::sync_with_stdio(false);
    std::cin.tie(0);

    int n;
    while(cin>>n){        
        memset(dp,0,sizeof(dp));
        memset(a,0,sizeof(a));
        for(int i=1;i<=n;i++){
            cin>>a[i];
        }//第一种写法
        for(int i=n-1;i>=2;i--){
            for(int j=i+1;j<=n;j++){
                dp[i][j] = INF;
                for(int k=i;k<j;k++){
                    dp[i][j] = min(dp[i][j],dp[i][k]+dp[k+1][j]+a[i-1]*a[j]*a[k]);
                }
            }
        }//第二种写法
        /*
        for(int d=2;d<n;d++){
            for(int i=2;i+d<=n + 1;i++){
                int j = i + d - 1;
                dp[i][j] = INF;
                for(int k=i;k<j;k++){
                    dp[i][j] = min(dp[i][j],dp[i][k] + dp[k+1][j] + a[i-1]*a[k]*a[j]);
                }
            }
        }*/
        cout<< dp[2][n] <<endl;
    }
    return 0;
}

参考资料:

传送门

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值