Description

The multiplication puzzle is played with a row of cards, each containing a single positive integer. During the move player takes one card out of the row and scores the number of points equal to the product of the number on the card taken and the numbers on the cards on the left and on the right of it. It is not allowed to take out the first and the last card in the row. After the final move, only two cards are left in the row.

The goal is to take cards in such order as to minimize the total number of scored points.

For example, if cards in the row contain numbers \(10\) \(1\) \(50\) \(20\) \(5\), player might take a card with 1, then 20 and 50, scoring

\[10*1*50 + 50*20*5 + 10*50*5 = 500+5000+2500 = 8000
\]

If he would take the cards in the opposite order, i.e. \(50\), then \(20\), then \(1\), the score would be

\[1*50*20 + 1*20*5 + 10*1*5 = 1000+100+50 = 1150.
\]

Input

The first line of the input contains the number of cards \(N (3 <= N <= 100)\). The second line contains \(N\) integers in the range from \(1\) to \(100\), separated by spaces.

Output

Output must contain a single integer - the minimal score.

Sample Input

6
10 1 50 50 20 5

Sample Output

3650

Source

Northeastern Europe 2001, Far-Eastern Subregion

Solution

题意简述:给定一个序列,取走一个数的代价是它乘上它相邻的两个数,两头的数不能取,求最小代价。

考虑区间DP。

令\(dp[i][j]\)表示把\(i+1\)~\(j-1\)的数都取走的最小代价。

然后进行区间DP,注意区间的长度的范围是\(3\)~\(n\)。

状态转移方程:

\[dp[i][j]=min(dp[i][j], dp[i][k] + dp[k][j] + a[i] * a[j] * a[k])
\]

Code

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <cctype> using namespace std; inline int gi()
{
int f = 1, x = 0; char c = getchar();
while (c < '0' || c > '9') { if (c == '-') f = -1; c = getchar();}
while (c >= '0' && c <= '9') { x = x * 10 + c - '0'; c = getchar();}
return f * x;
} int n, m, dp[103][103], a[103]; int main()
{
memset(dp, 0, sizeof(dp));//初始化
n = gi();
for (int i = 1; i <= n; i++) a[i] = gi();
for (int i = 3; i <= n; i++)//枚举区间长度
{
for (int j = 1; j + i <= n + 1; j++)//枚举起点
{
int k = j + i - 1;//终点
dp[j][k] = 1000000007;//当前区间的dp数组初始化
for (int l = j + 1; l <= k - 1; l++)//枚举分割点
{
dp[j][k] = min(dp[j][k], dp[j][l] + dp[l][k] + a[j] * a[k] * a[l]);//进行状态转移
}
}
}
printf("%d\n", dp[1][n]);//最后输出答案
return 0;//结束
}

题解【POJ1651】Multiplication Puzzle的更多相关文章

  1. POJ1651 Multiplication Puzzle —— DP 最优矩阵链乘 区间DP

    题目链接:https://vjudge.net/problem/POJ-1651 Multiplication Puzzle Time Limit: 1000MS   Memory Limit: 65 ...

  2. POJ1651:Multiplication Puzzle(区间DP)

    Description The multiplication puzzle is played with a row of cards, each containing a single positi ...

  3. POJ1651:Multiplication Puzzle(区间dp)

    Multiplication Puzzle Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 9419 Accepted: 5850 ...

  4. poj1651 Multiplication Puzzle

    比较特别的区间dp.小的区间转移大的区间时,也要枚举断点.不过和普通的区间dp比,断点有特殊意义.表示断点是区间最后取走的点.而且一个区间表示两端都不取走时中间取走的最小花费. #include &l ...

  5. POJ1651 Multiplication Puzzle【区间DP】

    LINK 每次删除一个数,代价是左右两边相邻的数的当前数的积 第一个和最后一个数不能删除 问最后只剩下第一个数的最后一个数的最小代价 思路 很简单的DP 正着考虑没有办法确定两边的数 那么就把每个区间 ...

  6. POJ1651 Multiplication Puzzle(相邻乘积之和最小,区间DP)

    http://blog.csdn.net/libin56842/article/details/9747021 http://www.cnblogs.com/devil-91/archive/2012 ...

  7. poj1651 Multiplication Puzzle(简单区间dp)

    题目链接:http://poj.org/problem?id=1651 题意:一系列的数字,除了头尾不能动,每次取出一个数字,这个数字与左右相邻数字的乘积为其价值, 最后将所有价值加起来,要求最小值. ...

  8. POJ1651 Multiplication Puzzle (区间DP)

    这道题的妙处在于把原问题看成矩阵连乘问题,求这些矩阵相乘的最小乘法次数,比如一个i*k矩阵乘一个k*j的矩阵,他们的乘法次数就是i*k*j (联想矩阵乘法的三层循环),题目说的取走一张牌,类似于矩阵相 ...

  9. ZOJ 1602 Multiplication Puzzle(区间DP)题解

    题意:n个数字的串,每取出一个数字的代价为该数字和左右的乘积(1.n不能取),问最小代价 思路:dp[i][j]表示把i~j取到只剩 i.j 的最小代价. 代码: #include<set> ...

随机推荐

  1. url 获取 geoserver 中对应的style

    http://userName:password@127.0.0.1:7093/geoserver/rest/workspaces/FAST/styles/AVG_RSRP.sld

  2. js - 文字

    居右 style="float:right;" 文字底部对齐(默认居中对齐) vertical-align:bottom; 文字居中 text-align:middle text- ...

  3. 安装python3.7.4时报错:Service Pack 1 is required to continue installation

    python3.7.4安装失败:Service Pack 1 is required to continue installation 解决办法: 点击报错页面中的“log file”,日志最后一行显 ...

  4. C++ stringstream用法(转)

    一直觉得C++ iostream的cout输出比起printf差了太多,今天查c++字符串拼接的时候偶然看到原来还有stringstream这个类,还是挺好用的,该类位于<sstream> ...

  5. 一次m2eclipse的安装大坑经历之http://m2eclipse.sonatype.org/sites/m2e

    m2eclipse 插件的安装在<Maven 实战>这本书上是这么说的: ”由于Eclipse默认没有集成对Maven的支持,幸运的是由Maven之父Jason Van Zyl创立的Son ...

  6. AcWing 487. 金明的预算方案

    #include <cstring> #include <iostream> #include <algorithm> #include <vector> ...

  7. centos7 tar.gz zip 解压命令

    tar负责打包,gzip负责压缩 tar -c: 建立压缩档案 -x:解压 -t:查看内容 -r:向压缩归档文件末尾追加文件 -u:更新原压缩包中的文件 这五个是独立的命令,压缩解压都要用到其中一个, ...

  8. poj1505(二分+贪心)

    "最大值尽量小"是一种很常见的优化目标. 关乎于炒书. 题目见此: http://poj.org/problem?id=1505 我的copy的代码如下: #include< ...

  9. C#String类型转换成Brush类型

    C#String类型转换成Brush类型: using System.Windows.Media; BrushConverter brushConverter = new BrushConverter ...

  10. c++指针实例

    #include <iostream> using namespace std; int main () { ; // 实际变量的声明 int* ip; // 指针变量的声明 ip = & ...