POJ1651:Multiplication Puzzle(区间DP 最优矩阵链乘)

题意:除了头尾不能动,每次取出一个数字,这个数字与左右相邻数字的乘积为其价值,最后将所有价值加起来,要求最小值

和最优矩阵链乘模型一样,最后取出的数决定了序,如果没学过最优矩阵连乘找重复子问题还是比较难找的

DP

//180K	0MS
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
int dp[110][110];
int n;
int num[110];
void debug()
{
    for(int i=1;i<=n;i++,puts(""))
        for(int j=1;j<=n;j++) printf("%6d",dp[i][j]);
}
int main()
{
    while(~scanf("%d",&n))
    {
        memset(dp,0,sizeof(dp));
        for(int i=1;i<=n;i++) scanf("%d",&num[i]);
        for(int l=1;l<=n;l++)
            for(int p=1;p<=n;p++)
                if(p+l<=n)
                    for(int k=p+1;k<p+l;k++)
                        dp[p][p+l]= k==p+1? dp[p][k]+dp[k][p+l]+num[p]*num[k]*num[p+l]:min(dp[p][p+l],dp[p][k]+dp[k][p+l]+num[p]*num[k]*num[p+l]) ;
      //  debug();
        printf("%d\n",dp[1][n]);
    }
    return 0;
}

记忆化的思路清晰一点:

//180K	0MS	C++	617B
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
int n;
int dp[110][110],num[110];
int morize(int l,int r)
{
    int &ans=dp[l][r];
    if(ans>=0) return ans;
    if(l+1==r) return ans=0;
    for(int k=l+1;k<r;k++)
        ans= k==l+1? morize(l,k)+morize(k,r)+num[l]*num[k]*num[r] : min(ans,morize(l,k)+morize(k,r)+num[l]*num[k]*num[r]);
    return ans;
}
int main()
{
    while(~scanf("%d",&n))
    {
        for(int i=1;i<=n;i++) scanf("%d",&num[i]);
        memset(dp,-1,sizeof(dp));
        printf("%d\n",morize(1,n));
    }
    return 0;
}
时间: 2024-10-25 06:19:42

POJ1651:Multiplication Puzzle(区间DP 最优矩阵链乘)的相关文章

POJ1651 Multiplication Puzzle 区间dp

题意:给一个序列,每次选一个数(记为b),计算左边离他最近的数(记为a),右边离他最近的数(记为c),计算a*b*c,sum+=a*b*c 重复操作直到剩下开头结尾两个数 不同的方案对应不同的sum 计算最小的sum值 分析:典型的区间dp,dp[i][j]表示把从i到j所有的数都选走得到的最小值 dp[i][j]=min(dp[i][j],dp[i][k-1]+dp[k+1][j]+num[k]*num[i-1]*num[j+1]): 注:记得预处理dp[i][i],i(2~n-1) #inc

POJ 1651 Multiplication Puzzle 区间DP

题意:在一个数字序列中, 取出不包括头和尾的所有数字, 每次取出一个数字的代价等于取出的这个数和左右两个数的乘积, 求总代价和最小的取法 此小到大递归 1 //#pragma comment(linker, "/STACK:167772160")//手动扩栈~~~~hdu 用c++交 2 #include <cstdio> 3 #include <cstring> 4 #include <cstdlib> 5 #include <iostrea

POJ 1651 Multiplication Puzzle 区间dp(水

题目链接:点击打开链 题意: 给定一个数组,每次可以选择内部的一个数 i 消除,获得的价值就是 a[i-1] * a[i] * a[i+1] 问最小价值 思路: dp[l,r] = min( dp[l, i] + dp[i, r] + a[l] * a[i] * a[r]); #include <cstdio> #include <iostream> #include <algorithm> #include <queue> #include <cst

dp-最优矩阵链乘

来自于紫书 题目大意 有\(n\)个矩阵组成的序列,设计一种运算顺序把它们依次乘起来,使得总运算量最小.假设第i个矩阵\(A_i\)是\(P_{i-1} \times P_i\)的.(\(n<=100\)) 例如:假设\(A\).\(B\).\(C\)分别是\(1 \times 50 , 50 \times 20 , 20 \times 5\) \(A \times (B \times C)\)的运算量为\(1 \times 50 \times 5 + (50 \times 20 \times

uva348 最优矩阵链乘 经典区间dp

// uva348 最优矩阵链乘 // 典型的区间dp // dp[i][j] 表示矩阵i到j链乘所得到的最小花费 // dp[i][j] = min(dp[i][k]+dp[k+1][j]+a[i].pl*a[k].pr*a[j].pr); // 在区间i到j上找一个k使得dp[i][k]+dp[k+1][j]这两部分的和在加上最后的 // a[i].pl*a[k].pr*p[i].pr的最小值; // 能有这样的状态关键是; P =A[1] * A[2] * .... * A[K] // 和

uva348Optimal Array Multiplication Sequence (最优矩阵链乘+路径输出)

Optimal Array Multiplication Sequence Time Limit:3000MS Memory Limit:0KB 64bit IO Format:%lld & %llu Submit Status Practice UVA 348 Appoint description: Description Download as PDF Given two arrays A and B, we can determine the array C = AB using the

ZOJ3541:The Last Puzzle(区间DP)

There is one last gate between the hero and the dragon. But opening the gate isn't an easy task. There were n buttons list in a straight line in front of the gate and each with an integer on it. Like other puzzles the hero had solved before, if all b

POJ1651——Multiplication Puzzle

Multiplication Puzzle Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 6511   Accepted: 3964 Description The multiplication puzzle is played with a row of cards, each containing a single positive integer. During the move player takes one

UVA 348 Optimal Array Multiplication Sequence(最优矩阵链乘)

L - Optimal Array Multiplication Sequence Time Limit:3000MS     Memory Limit:0KB     64bit IO Format:%lld & %llu Submit Status Practice UVA 348 Appoint description:  acmparand  (2013-08-02)System Crawler  (2015-08-04) Description Given two arrays A a