每日一题(4)——动态规划《Introduction to Algorithms》总结篇
来源:互联网 发布:网络信息化领导小组 编辑:程序博客网 时间:2024/06/08 13:51
概述
同分治法一样动态规划是通过组合子问题的解而解决整个问题的
动态规划的4个步骤:
1.描述最优解结构;
2.递归定义最优解的值;
3.按自底向上方式计算最优解;
4.由计算出的结果构造最优解;(1-3步是基础,第4步可以略去)
动态规划特点,包含重复子问题,可以用图结构保存中间结果,不用重复计算。
1.装配线调度
(PS:这图太磕碜了,没办法,原来网页版的算法导论在PKU的服务器上有,现在不让访问了,悲剧啊,NB学校就是NB,我等P民只能仰望啊~闲扯啊,各位看官将就着看吧~)
问题:每个车间生产需要生产时间,从不同的生产线调配到另一个生产线需要调配时间,计算最小时间?
1.描述最优解结构(划分子问题,子结构):按生产线长度划分;
2.递归定义最优解的值:递归求解每个长度的最优解;
3.按自底向上方式计算最优解,按长度从短到长求解;
输入:生产线长度,每个车间的生产时间,每个车间之间的调度时间,
输出:最短长度;
example:
Input:
6
7 9 3 4 8 4
8 5 6 4 5 7
2 3 1 3 4
2 1 2 2 1
output
38
#include <iostream>using namespace std;int minT[2][100];int a[2][100], t[2][100];int e[2]={2,4}, x[2]={3,2};int cal( int k, int num){if (num==1) {minT[k][1] = e[k]+a[k][1];return minT[k][1];}if(minT[k][num]>0) return minT[k][num];else{minT[k][num] = min(cal(k, num-1), cal((k+1)%2, num-1)+t[(k+1)%2][num-1] )+a[k][num];return minT[k][num];}}int main(){memset(minT, 0, sizeof(minT));int count;cin>>count;cout<<"a & t: "<<endl;for(int i=1 ;i<=count; i++) cin>>a[0][i];for(int i=1 ;i<=count; i++) cin>>a[1][i];for(int i=1 ;i<=count-1; i++) cin>>t[0][i];for(int i=1 ;i<=count-1; i++) cin>>t[1][i];int minCost = min(cal(0,count)+x[0] ,cal(1,count)+x[1]);cout<<"MIN:"<<minCost<<endl;}
2.矩阵链乘法
n个矩阵连乘,A1,A2,A3,... An; 相乘的顺序不同,
A1,A2,A3,A4会产生5种不同的组合:
1.(A1 (A2 (A3*A4) ) ) 2. (A1 ( (A2*A3) A4) ) 3. ( (A1*A2)(A3*A4) ) 4.( ( (A1(A2*A3) )A4 ) 5.(((A1*A2) A3) A4)
根据不同的组合,计算相乘的次数也不同
要求输出最小相乘次数
输入
矩阵数;(一个值 n)
矩阵的横纵坐标:(n+1个值 )因为后矩阵的行数等于前坐标的列数
要求计算区间:
输出:
区间的最小计算次数
for example:
输入:
6
30 35 15 5 10 20 25
1 6
输出:
15125
1.描述最优解结构(划分子问题,子结构):按组合划分;
2.递归定义最优解的值:递归求解每组合的最优解;(并保存在矩阵的相应位置中)
3.按自底向上方式计算最优解,按区间从短到长求解;(可以不断调用矩阵,如果矩阵中有的话)
动态规划方程
s[i,j]=0 (if i=j);
s[i,j]=s[i,k]+s[k+1,j]+p[i-1]p[k]p[j];
#include <iostream>using namespace std;#define INF 1000000000;double s[100][100];int p[101];double minMul(int low, int high){if(low==high) return 0;if(s[low][high]>0) return s[low][high];double minTmp = INF;double tmp;for (int k=low; k<high; k++){tmp=minMul(low,k)+minMul(k+1,high)+p[low-1]*p[k]*p[high];if(tmp<minTmp)minTmp = tmp;}s[low][high]=minTmp;return minTmp;}int main(){memset(s,0,sizeof(s));int n;cin>>n;for(int i=0; i<=n; i++) cin>>p[i];int left,right;cin>>left>>right;double minM = minMul(left,right);cout<<minM<<endl;}
3.最长公共子序列
给出两个序列,要求给出这两个序列中的最长公共子序列长度;可以不连续,但必须按顺序
a="ABCBDAB", b="BDCABA" 的最长公共子序列长度为4,为"BCBA"
典型的使用矩阵保存中间值,向上不断求解最优解(相同类型:求解字符串间最短距离)
动态规划方程:
if(i==0 或 j==0)
当f(a[i]==b[j])时 A[i][j]=1;否则 A[i][j]=0;
else:
当f(a[i]==b[j])时 A[i][j]=A[i-1][j-1]+1; 否则 A[i][j]=max(A[i-1][j], A[i][j-1]);
#include <iostream>#include <string>using namespace std;string a="ABCBDAB", b="BDCABA";int A[100][100];int main(){int la = a.length();int lb = b.length();for(int i=0; i<la; i++){for(int j=0; j<lb; j++){if(i==0 || j==0){if(a[i]==b[j]) A[i][j]=1;else A[i][j]=0;}else{if(a[i]!=b[j]) A[i][j] = max(A[i-1][j], A[i][j-1]);else A[i][j]=A[i-1][j-1]+1;}}}cout<<A[la-1][lb-1]<<endl;}
4.构造最优二叉查找树
每个节点具有一个期望p,每个叶子节点具有一个期望q,要构造一棵二叉树使得总体查找期望最小。
每个节点具有一个期望p,每个叶子节点具有一个期望q,要构造一棵二叉树使得总体查找期望最小。
Input
6
0.15 0.1 0.05 0.1 0.2
0.05 0.1 0.05 0.05 0.05 0.1
动态规划方程:
概率和:
W(i,j)=q(j) (if i>j 叶子节点)
W(i,j)=W(i,r-1)+p(r)+W(r+1,j)
查找期望:
E(i,j)=W(i,j)(if i>j 叶子节点)
E(i,j)=E(i,r-1)+w(i,j)+E(r+1,j)
#include <iostream>#define INF 1000000;using namespace std;float p[100],q[100];float w[100][100], e[100][100];float calW(int i, int j){if(w[i][j]>0) return w[i][j];if(i > j){w[i][j] = q[j];return w[i][j];}float minw=INF;for (int r=i; r<=j; r++){w[i][j] = calW(i,r-1)+p[r]+calW(r+1,j);if(w[i][j]<minw) minw = w[i][j];}w[i][j] = minw;return w[i][j];}float calE(int i, int j){if(e[i][j]>0) return e[i][j];if(i>j) {e[i][j] = calW(i,j);return e[i][j];}float minE=INF;for (int r=i; r<=j; r++){e[i][j] = calE(i, r-1)+calW(i, j)+calE(r+1, j);if(e[i][j]<minE) minE = e[i][j];}e[i][j] = minE;return e[i][j];}int main(){int n;memset(p,0,sizeof(p));memset(q,0,sizeof(q));cin>>n;for (int i=1; i<n; i++) cin>>p[i]; //non-leaffor (int j=0; j<n; j++) cin>>q[j]; //leaffloat all15=calE(1,5);cout<<all15<<endl;}
- 每日一题(4)——动态规划《Introduction to Algorithms》总结篇
- 每日一题(4)——动态规划《Introduction to Algorithms》总结篇
- 每日一题(1)——滑雪问题(动态规划)
- 每日一题(1)——滑雪问题(动态规划)
- 写在前面的话——Introduction to Algorithms Third Edition
- 2. Getting Started——Introduction to Algorithms Third Edition
- About Introduction to Algorithms
- Introduction to Algorithms
- Introduction to Algorithms
- BUBBLESORT: INTRODUCTION TO ALGORITHMS
- Introduction to Algorithms
- 每日一题(5)——公正陪审团问题(动态规划)
- 每日一题(7)——0-1背包问题(动态规划)
- 每日一题(18)——买书问题(动态规划)
- 每日一题(19)——数组分割(动态规划)
- 每日一题(7)——0-1背包问题(动态规划)
- 每日一题(18)——买书问题(动态规划)
- 每日一题(19)——数组分割(动态规划)
- python的调试
- java InetAddress.getLocalHost() 在linux里实现
- Asp.net_GridView隔行变色和光棒效果[更新]
- HTML布局定位:scrollLeft,scrollWidth,clientWidth,offsetWidth之完全带图详解
- 调试器开发 ﹣ 在qemu裹创造一个debug server的stub
- 每日一题(4)——动态规划《Introduction to Algorithms》总结篇
- android中的dialog的总结
- Android流量统计TrafficStats类的使用
- RH9里/var/lock/subsys目录的作用
- 【Linux&音频】Alsa音频编程【精华】
- 用C语言显示汉字的演示程序
- WPF(小结4)TreeView的数据分层模板
- ibatis
- 普适GIS——ArcGIS Online试用 (1)