简单动态规划
来源:互联网 发布:奔驰数据库 编辑:程序博客网 时间:2024/05/21 10:01
动态规划问题必须同时具有如下二个要素:
最优子结构
如果问题的一个最优解中包含了子问题的最优解,则该问题具有最优子结构。
动态规划以自底向上的方式来利用最优子结构
重叠子问题
子问题的空间要“很小”,也就是用来解原问题的递归算法可反复的解同样的子问题,
而不是产生新的子问题。DP通过每个子问题只解一次,把解保存在一个需要时就可以查到的表中,
每次查表的时间为常数。
装配线调度
ans[i][j]表示从起点到装配置S(i,j)的最快可能时间
cost[i][j]表示在装配站S(i,j)的装配时间
trans[i][j]从装配下S(i,j)移到另一条装配线所花费的时间
状态方程:
ans[0][i] = cost[0][0] + cost[0][1] if 1 == i
ans[1][i] = cost[1][0] + cost[1][1]
ans[0][i] = min(ans[1][i-1]+trans[1][i-2]+cost[0][i], if i >= 2
ans[0][i-1]+cost[0][i])
ans[1][i] = min(ans[0][i-1]+trans[0][i-2]+cost[1][i],
ans[1][i-1]+cost[1][i])
#include <iostream>
using std::cout;
using std::endl;
unsigned int cost[2][8] = {
{2, 7, 9, 3, 4, 8, 4, 3},
{4, 8, 5, 6, 4, 5, 7, 2}
};
unsigned int trans[2][5] = {
{2, 3, 1, 3, 4},
{2, 1, 2, 2, 1}
};
unsigned int ans[2][7] = { 0 };
unsigned int used[2][8] = { 0 };
unsigned int resTime = 0;
unsigned int resLine = 0;
void assembly()
{
ans[0][1] = cost[0][0] + cost[0][1];
ans[1][1] = cost[1][0] + cost[1][1];
for (int i = 2; i <= 6; ++i)
{
if (ans[0][i-1] > (ans[1][i-1] + trans[1][i-2]))
{
ans[0][i] = ans[1][i-1] + trans[1][i-2] + cost[0][i];
used[0][i] = 2;
}
else
{
ans[0][i] = ans[0][i-1] + cost[0][i];
used[0][i] = 1;
}
if (ans[1][i-1] > (ans[0][i-1] + trans[0][i-2]))
{
ans[1][i] = ans[0][i-1] + trans[0][i-2] + cost[1][i];
used[1][i] = 1;
}
else
{
ans[1][i] = ans[1][i-1] + cost[1][i];
used[1][i] = 2;
}
}
if ((ans[0][6] + cost[0][7]) > (ans[1][6] + cost[1][7]))
{
resTime = ans[1][6] + cost[1][7];
resLine = 2;
}
else
{
resTime = ans[0][6] + cost[0][7];
resLine = 1;
}
}
void show()
{
int tmp = resLine;
cout << "minTime = " << resTime << endl;
cout << "line = " << resLine << " ,station = 6"<< endl;
for (int i = 6; i >= 2; --i)
{
cout << "line = " << used[tmp-1][i] << " ,station = " << i-1 << endl;
tmp = used[tmp-1][i];
}
}
int main()
{
assembly();
show();
return 0;
}
矩阵链乘法
val[i][j]表示计算矩阵A(i,j)所需的标量乘法运算次数的最小值
状态方程
val[i][j] = 0 if i == j
min(val[i][k]+val[k+1][j]+
matrix[i-1]*matrix[k]*matrix[j]) if i < j && i >= k && k < j
#include <iostream>
using std::cout;
using std::endl;
int val[7][7] = { 0 };
int separate[7][7] = { 0 };
void matrix_chain_order()
{
int matrix[7] = {30, 35, 15, 5, 10, 20, 25};
int num = 6;
for (int l = 2; l <= 6; ++l) // l is the chain length
for (int i = 1; i <= num-l+1; ++i)
{
int j = i+l-1;
val[i][j] = 0x0ffff;
for (int k = i; k <= j-1; ++k)
{
int tmp = val[i][k] + val[k+1][j] +
matrix[i-1]*matrix[k]*matrix[j];
if (tmp < val[i][j])
{
val[i][j] = tmp;
separate[i][j] = k;
}
}
}
}
void print_optimal_parents(int i, int j)
{
if (i == j)
cout << "A" << i;
else
{
cout << "(";
print_optimal_parents(i, separate[i][j]);
print_optimal_parents(separate[i][j]+1, j);
cout << ")";
}
}
int main()
{
matrix_chain_order();
print_optimal_parents(1, 6);
return 0;
}
最长公共子序列
给定两个序列 X = {x1, x2, ......, xm } 和 Y = {y1, y2, ......, yn },
找出 X 和 Y 的最长公共子序列。
一个给定序列的子序列是在该序列中删去若干个元素后得到的序列。
给定两个序列 X 和 Y ,当另一序列 Z 既是 X 的子序列又是 Y 的子序列时,
称 Z 是序列 X 和 Y 的公共子序列。
例如,若 X = {A, B, C, B, D, A, B },
Y = {B, D, C, A, B, A },
序列{B, C, A }是 X 和 Y 的一个公共子序列,
序列{B, C, B, A }也是 X 和 Y 的一个公共子序列,且为最长公共子序列。
res[i][j]表示X的长度为i,Y的长度为j时,最长公共子序列大小
flag[i][j]表示X的长度为i,Y的长度为j时,X,Y移动的方向
-1: 仅X向后移动一位
0: X与Y同时向后移动一位
1: 仅Y向后移动一位
状态方程
0 if 0 ==i || 0 ==j
res[i][j]= res[i-1][j-1]+1 if X[i-1] == Y[j-1]
max(res[i-1][j], res[i][j-1]) if X[i-1] != Y[j-1]
#include <iostream>
#include <string.h>
using std::cout;
using std::endl;
int res[100][100] = { 0 };
short flag[100][100] = { 0 };
void lcs_length(char str1[], int len1, char str2[], int len2)
{
for (int i = 1; i <= len1; ++i)
for (int j = 1; j <= len2; ++j)
{
if (str1[i-1] == str2[j-1])
{
res[i][j] = res[i-1][j-1] + 1;
flag[i][j] = 0;
}
else
{
if (res[i-1][j] >= res[i][j-1])
{
res[i][j] = res[i-1][j];
flag[i][j] = -1;
}
else
{
res[i][j] = res[i][j-1];
flag[i][j] = 1;
}
}
}
}
void lcs_print(char str1[], int i, int j)
{
if (0 == i || 0 == j)
return ;
if (0 == flag[i][j])
{
lcs_print(str1, i-1, j-1);
cout << str1[i-1];
}
else if (-1 == flag[i][j])
lcs_print(str1, i-1, j);
else
lcs_print(str1, i, j-1);
}
int main()
{
char str1[] = "ABCBDAB";
char str2[] = "BDCABA";
int len1 = strlen(str1);
int len2 = strlen(str2);
lcs_length(str1, len1, str2, len2);
cout << "lcs = " << res[len1][len2] << endl;
lcs_print(str1, len1, len2);
cout << endl;
return 0;
}
63,0-1 97%
- poj2479_简单动态规划
- 动态规划简单实例
- 简单动态规划
- 简单动态规划总结
- 动态规划-简单了解
- 简单动态规划问题
- 简单动态规划
- 简单动态规划总结
- 动态规划简单理解
- 简单区间动态规划
- leetcode46简单动态规划
- poj 1157 简单动态规划
- pku acm1579简单动态规划
- DP 动态规划简单总结
- hdu 1176 简单动态规划
- hdu 1069 简单动态规划
- hdu 1466 简单动态规划
- hdu 2059 简单动态规划
- POJ:2240 Arbitrage(bellmanford判负环变形题)
- 用一行替换txt中的一行
- 死锁
- CKEditor图片上传实现详细步骤(使用Struts 2)
- 组合数学--置换群
- 简单动态规划
- 关键词推荐工具中的用户引导机制之四:种子query推荐
- ubuntu下jdk、tomcat、mysql安装配置
- 【js学习笔记-055】比较方法
- 使用oracle发邮件
- How to make a java class immutable
- C++中的类所占内存空间总结
- Django 生成PDF(三)——关于RML
- Ubuntu如何清理系统垃圾