DP--矩阵连乘
2015-11-08 10:58
399 查看
问题:给定n个矩阵,求乘法次数的最小值
1)最优子结构:
一个简单的解决办法是把括号放在所有可能的地方,计算每个位置的成本,并返回最小值。对于一个长度为n的链,我们有n-1种方法放置第一组括号。
例如,如果给定的链是4个矩阵。让矩阵连为ABCD,则有3种方式放第一组括号:A(BCD),(AB)CD和(ABC)D。
所以,当我们把一组括号,我们把问题分解成更小的尺寸的子问题。因此,这个问题具有最优子结构性质,可以使用递归容易解决。
2)重叠子问题
以下是递归的实现,只需用到上面的最优子结构性质
实际上是把矩阵乘法区间拆分,下面是迭代写法:这里只给出dp函数部分,其余同上
1)最优子结构:
一个简单的解决办法是把括号放在所有可能的地方,计算每个位置的成本,并返回最小值。对于一个长度为n的链,我们有n-1种方法放置第一组括号。
例如,如果给定的链是4个矩阵。让矩阵连为ABCD,则有3种方式放第一组括号:A(BCD),(AB)CD和(ABC)D。
所以,当我们把一组括号,我们把问题分解成更小的尺寸的子问题。因此,这个问题具有最优子结构性质,可以使用递归容易解决。
2)重叠子问题
以下是递归的实现,只需用到上面的最优子结构性质
#include <iostream> #include <algorithm> #include <cstdio> #include <cstring> using namespace std; const int maxn = 50; int p[maxn], d[maxn][maxn]; int chain(int i, int j) { if(i == j) return 0; if(d[i][j] > 0) return d[i][j]; int ans = 0x3f3f3f3f; for(int k=i; k<j; k++) ans = min(ans, chain(i, k)+chain(k+1, j)+p[i-1]*p[k]*p[j]); return d[i][j] = ans; } int main() { int n; while(~scanf("%d", &n)) { for(int i=0; i<=n; i++) scanf("%d", &p[i]); memset(d, 0, sizeof(d)); printf("%d\n", chain(1, n)); } return 0; }
实际上是把矩阵乘法区间拆分,下面是迭代写法:这里只给出dp函数部分,其余同上
int chain(int n) { for(int div=2; div<=n; div++) { for(int i=1; i<=n-div+2; i++) { int j = i + div - 1; d[i][j] = 0x3f3f3f3f; for(int k=i; k<j; k++) d[i][j] = min(d[i][j], d[i][k]+d[k+1][j]+p[i-1]*p[k]*p[j]); } } return d[1] ; }
相关文章推荐
- poj2549
- Openstack Murano(kilo)二次开发之添加Volume
- BFC, IFC
- ARP协议工作过程
- mysql show命令集合
- 信息安全系统设计基础第八周学习总结
- less和scss
- Java动态代理机制
- Linux 学习(3)-- kernel版本号的修改
- Python学习笔记(3)range的用法
- ApplicationContext的三种实现方式以及在web.xml配置的两种方式
- 哪种性格的人更长寿
- [转]python os模块 常用命令
- 树链剖分模版
- 浅析Linux计算机进程地址空间与内核装载ELF
- Windows下用ndk编译ffmpeg
- volatile的详细讲解
- 经典SQL语句大全
- 十进制大数的加法运算
- java 多线程之卖票两种方式