题目链接:https://vjudge.net/problem/POJ-1651

Multiplication Puzzle
Time Limit: 1000MS   Memory Limit: 65536K
Total Submissions: 11239   Accepted: 6980

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

题意:

有N张写有数字的卡片排成一行,按一定次序从中拿走N-2张(第1张和最后一张不能拿),每次只拿一张,取走一张卡片的同时,会得到一个分数,分值的计算方法是:要拿的卡片,和它左右两边的卡片,这三张卡片上数字的乘积。按不同的顺序取走N-2张卡片,得到的总分可能不相同,求出给定一组卡片按上述规则拿取的最小得分。

题解:

最优矩阵链乘问题。刘汝佳紫书P277。

1.在取牌的过程中,必定存在一张最后取的牌,可知这张牌左右两边的牌都已经取完了(除了两端点)。于是“最后取的牌”,就把区间分成了两段。由于这两段区间的取牌(即得分情况)互不影响,故可以分开求值。那又怎样才能知道最后取哪张牌才能使得取值最优呢?枚举区间内每一张牌作为最后取的牌,取最优值。

2.对于被分开的左右两段区间,又可各自根据步骤1得到最优值。

3.紫书中区间的写法是左闭右开,但个人觉得不好理解,于是就写成自己所熟悉的闭区间。

记忆化搜索:

 #include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <string>
#include <vector>
#include <map>
#include <set>
#include <queue>
#include <sstream>
#include <algorithm>
using namespace std;
#define pb push_back
#define mp make_pair
#define ms(a, b) memset((a), (b), sizeof(a))
#define eps 0.0000001
typedef long long LL;
const int INF = 2e9;
const LL LNF = 9e18;
const int mod = 1e9+;
const int maxn = +; LL p[maxn], dp[maxn][maxn]; LL dfs(int l, int r) //区间[l, r]中每个元素都可以取走
{
if(l>r) return ;
if(dp[l][r]!=LNF) return dp[l][r]; for(int k = l; k<=r; k++)
dp[l][r] = min(dp[l][r], dfs(l,k-) + dfs(k+,r) + p[l-]*p[k]*p[r+]); return dp[l][r];
} int main()
{
int n;
scanf("%d",&n);
for(int i = ; i<=n; i++)
scanf("%lld",&p[i]); for(int i = ; i<n; i++)
for(int j = ; j<=n; j++)
dp[i][j] = LNF; cout<<dfs(, n-)<<endl;
return ;
}

递推:

 #include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <string>
#include <vector>
#include <map>
#include <set>
#include <queue>
#include <sstream>
#include <algorithm>
using namespace std;
#define pb push_back
#define mp make_pair
#define ms(a, b) memset((a), (b), sizeof(a))
#define eps 0.0000001
typedef long long LL;
const int INF = 2e9;
const LL LNF = 9e18;
const int mod = 1e9+;
const int maxn = +; LL p[maxn], dp[maxn][maxn]; int main()
{
int n;
scanf("%d",&n);
for(int i = ; i<=n; i++)
scanf("%lld",&p[i]); memset(dp, , sizeof(dp));
for(int l = ; l<=n-; l++)
for(int r = l; r<=n-; r++)
dp[l][r] = LNF; for(int len = ; len<=n-; len++)
{
for(int l = ; l<=n--len+; l++) //能取的区间为[2, n-1]
{
int r = l + len - ;
for(int k = l; k<=r; k++)
dp[l][r] = min(dp[l][r], dp[l][k-] + dp[k+][r] + p[l-]*p[k]*p[r+]);
}
} cout<< dp[][n-] <<endl; }

POJ1651 Multiplication Puzzle —— DP 最优矩阵链乘 区间DP的更多相关文章

  1. UVa 10003 切木棍(区间DP+最优矩阵链乘)

    https://vjudge.net/problem/UVA-10003 题意: 有一根长度为L的棍子,还有n个切割点的位置.你的任务是在这些切割点的位置处把棍子切成n+1部分,使得总切割费用最小.每 ...

  2. ZOJ 1276 "Optimal Array Multiplication Sequence"(最优矩阵链乘问题+区间DP)

    传送门 •题意 矩阵 A(n×m) 和矩阵 B(m×k) 相乘,共做 n×m×k 次乘法运算: 给你 n 个矩阵,求这 n 个矩阵的最优结合方式,使得做的总乘法运算次数最少: •题解 定义dp(i,j ...

  3. POJ 1651 Multiplication Puzzle(类似矩阵连乘 区间dp)

    传送门:http://poj.org/problem?id=1651 Multiplication Puzzle Time Limit: 1000MS   Memory Limit: 65536K T ...

  4. POJ1651:Multiplication Puzzle(区间DP)

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

  5. POJ1651:Multiplication Puzzle(区间dp)

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

  6. poj1651 Multiplication Puzzle

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

  7. dp方法论——由矩阵相乘问题学习dp解题思路

    前篇戳:dp入门——由分杆问题认识动态规划 导语 刷过一些算法题,就会十分珍惜“方法论”这种东西.Leetcode上只有题目.讨论和答案,没有方法论.往往答案看起来十分切中要害,但是从看题目到得到思路 ...

  8. 蓝桥 ADV-232 算法提高 矩阵乘法 【区间DP】

      算法提高 矩阵乘法   时间限制:3.0s   内存限制:256.0MB      问题描述 有n个矩阵,大小分别为a0*a1, a1*a2, a2*a3, ..., a[n-1]*a[n],现要 ...

  9. tyvj 1198 矩阵连乘——区间dp

    tyvj 1198 矩阵连乘 题目描述 一个n*m矩阵由n行m列共n*m个数排列而成.两个矩阵A和B可以相乘当且仅当A的列数等于B的行数.一个N*M的矩阵乘以一个M*P的矩阵等于一个N*P的矩阵,运算 ...

随机推荐

  1. 软件包管理器(bzoj 4196)

    Description Linux用户和OSX用户一定对软件包管理器不会陌生.通过软件包管理器,你可以通过一行命令安装某一个软件包,然后软件包管理器会帮助你从软件源下载软件包,同时自动解决所有的依赖( ...

  2. AOP面向方面(切面)编程

    1.引言 软件开发的目标是要对世界的部分元素或者信息流建立模型,实现软件系统的工程需要将系统分解成可以创建和管理的模块.于是出现了以系统模块化特性的面向对象程序设计技术.模块化的面向对象编程极度极地提 ...

  3. 洛谷 P 1330 封锁阳光大学

    题目描述 曹是一只爱刷街的老曹,暑假期间,他每天都欢快地在阳光大学的校园里刷街.河蟹看到欢快的曹,感到不爽.河蟹决定封锁阳光大学,不让曹刷街. 阳光大学的校园是一张由N个点构成的无向图,N个点之间由M ...

  4. 清清月儿.net学习技术资料网站

    原文发布时间为:2008-08-03 -- 来源于本人的百度文章 [由搬家工具导入] http://blog.csdn.net/21aspnet/

  5. 自动化测试框架之robot framework的应用分析

    序言:很多人都对自动化测试框架痴迷,我曾经也痴迷过一段时间,以前觉得自己对框架说的头头是道,现在回过头来看以前,说归说,但在如何应用还是欠缺,这一段时间,自己经历了一系列框架的构建和应用的时期,所以, ...

  6. python常用模块详解(一)

    一.简介 模块是一个保存了Python代码的文件.模块能定义函数,类和变量.模块里也能包含可执行的代码 模块分为三种: 自定义模块 内置标准模块 开源模块(第三方) 自定义模块: 模块导入 impor ...

  7. H5 折线图插件

    一.可以使用Highcharts,参考网址:https://api.hcharts.cn/highcharts: 二.可以使用Echarts,参考网址:http://echarts.baidu.com ...

  8. 【chrome错误】Cross origin requests are only supported for protocol schemes: http, data,chrome-extension, https, chrome-extension-reso

    使用ajax请求本地文件,chrome会报跨域错误. XMLHttpRequest cannot loadfile:///C:/Users/Li/Desktop/images/alist.json.C ...

  9. BUPT复试专题—最小距离查询(2013)

    题目描述 给定一个由小写字母a到z组成的字符串S,其中第i个字符为S[i](下标从0开始).你需要完成下面两个操作:INSERT c  其中c是一个待输入的字符.你需要在字符串的末尾添加这个字符.保证 ...

  10. LOCAL_CFLAGS参数说明

    1.-Wall 是打开警告开关 2.-O 代表默认优化,可选:-O0不优化,-O1低级优化,-O2中级优化,-O3高级优化,-Os代码空间优化 3.-g 是生成调试信息,生成的可执行文件具有和源代码关 ...