码迷,mamicode.com
首页 > 其他好文 > 详细

紫书第9章 动态规划初步

时间:2016-03-12 18:34:01      阅读:178      评论:0      收藏:0      [点我收藏+]

标签:

9.1 数字三角形

9.1.2 记忆化搜索与递推

方法1:递归计算。程序如下(需注意边界处理):

int solve(int i,int j)
{
     return a[i][j] + (i==n ?0:max(solve(i+1,j),solve(i+1,j+1));
}

用直接递归的方法计算状态转移方程,效率往往十分低下。其原因是相同的子问题被重复计算了多次。

 

方法2:递推计算。程序如下(需再次注意边界处理):

int i, j;
for(j = 1; j <= n; j++) d[n][j] = a[n][j];
for(i = n-1; i >= 1; i——)
for(j = 1; j <= i; j++)
d[i][j] = a[i][j] + max(d[i+1][j],d[i+1][j+1]);

程序的时间复杂度显然是O(n2),但为什么可以这样计算呢?原因在于:i是 逆序枚举的,因此在计算d[i][j]前,它所需要的d[i+1][j]和d[i+1][j+1]一定已经计算出来了。

 

方法3:记忆化搜索。程序分成两部分。首先用“memset(d,-1,sizeof(d));”把d全部初始化为-1,然后编写递归函数(1):

int solve(int i, int j){
if(d[i][j] >= 0) return d[i][j];
return d[i][j] = a[i][j] + (i == n ? 0 : max(solve(i+1,j),solve(i+1,j+1)));

 

9.2 DAG上的动态规划

9.2.1 DAG模型
嵌套矩形问题。有n个矩形,每个矩形可以用两个整数a、b描述,表示它的长和宽。矩
形X(a,b)可以嵌套在矩形Y(c, d)中,当且仅当a<c,b<d,或者b<c,a<d(相当于把矩
形X旋转90°)。例如,(1, 5)可以嵌套在(6, 2)内,但不能嵌套在(3, 4)内。你的任务是选出尽
量多的矩形排成一行,使得除了最后一个之外,每一个矩形都可以嵌套在下一个矩形内。如
果有多解,矩形编号的字典序应尽量小。

int dp(int i)
{
     int& ans = d[i];
     if(ans>0) return ans;
     for(int j = 0;j<n;j++)
     {
          if(G[i][j])
               ans = max(ans,dp(j)+1);
     }
     return ans;
}

 

原题还有一个要求:如果有多个最优解,矩形编号的字典序应最小。还记得第6章中的
例题“理想路径”吗?方法与其类似。将所有d值计算出来以后,选择最大d[i]所对应的i。如
果有多个i,则选择最小的i,这样才能保证字典序最小。接下来可以选择d(i)=d(j)+1且
(i,j)∈E的任何一个j。为了让方案的字典序最小,应选择其中最小的j

void print_ans(int i) {2
printf("%d ", i);
for(int j = 1; j <= n; j++) if(G[i][j] && d[i] == d[j]+1){
print_ans(j);
break;
}
}

 

9.2.3 固定终点的最长路和最短路

int dp(int s)
{
     int& ans = d[s];
     if(ans>=0) return ans;
     for(int i = 0;i<n;i++)
     {
          if(s>=v[i]) ans = max(ans,dp(s-v[i])+1);
     }
     return ans;
}

 

紫书第9章 动态规划初步

标签:

原文地址:http://www.cnblogs.com/qlky/p/5269474.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!