详解动态规划法
来源:互联网 发布:olga软件 编辑:程序博客网 时间:2024/06/05 00:49
看了刘汝佳的紫书:
一、从经典的三角形数问题开始。。
5357 9101281 62
(。。自我吐槽一下这个排版。。)
一个由非负整数组成的三角形,它的第一行有1个数,这个数的左下和右下各有一个数,以此类推...现在从第一行的数开始,每次往左下或者右下走一格,直到到达三角形底
部,要求所走的数字最后加起来最大。
考虑用二维数组储存数据,每个格子可以这样编号:
(1,1)
(2,1) (2,2)
(3,1) (3,2) (3,3)
(4,1) (4,2) (4,3) (4,4)
当前状态下如果要取得最大,必须保证下一个状态也是最大的,比如说在(i,j)这个位置,下一个状态可能是(i+1,j+1),或者(i+1,j),这样,如果用函数d(i,j)表示在(i,j)位取得的最大值,那么就有关系式:d(i,j)=a(i,j)+max(d(i+1,j+1),d(i+1,j))
边界是当i=n的时候,第二项不存在,应该取0。
找到状态转移方程后可以:
1)递归求解
2)递推计算(逆向地)
3)记忆化搜索
使用memset(array,0,sizeof(array))或者memset(array,-1,sizeof(array)),表示初始时数组中的项都没有被计算过,然后再递归函数里加上控制条件保证每一项只被算一次,例如对于三角形问题:
memset(d,-1,sizeof(d));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+1),solve(i+1,j)));}
二、DAG上的动态规划
把问题归结为求DAG上的最长路或者最短路。
例如从i出发的最长路d(i)=max(d(j)+1|(i,j)∈E),其中(i,j)表示从i出发的边,E表示边集。
三、线性结构的动规
(1)最大上升子序列(LIS)问题
如果用d[i]来表示位置i处的LIS长度,那么d[i]就和它前面的所有位置都有关,这个关系是:d[i]等于它前面的位置里最大的LIS值加上1(如果i位置的数比前面位置大的话),也就是说:d[i]=max{d[j]|j<i,a[j]<a[i]}+1,其中a[]保存了这个序列。
最后的结果应该是d[]中的最大值。
下面这道题来自POJ(吐槽一下POJ长得好丑。。。还是浙大的PAT好哇:-))
POJ2533:
Description
Your program, when given the numeric sequence, must find the length of its longest ordered subsequence.
Input
Output
Sample Input
71 7 3 5 9 4 8
Sample Output
4
Source
#include<stdio.h>#include<stdlib.h>int main(){int i,j,N;int* a;//store the inputint* d;//store the resultint max=0,dmax=1;scanf("%d",&N);a=(int*)malloc(sizeof(int)*(N+1));d=(int*)malloc(sizeof(int)*(N+1));for(i=1;i<=N;i++)scanf("%d",&a[i]);d[1]=1;//only a numberfor(i=2;i<=N;i++){max=0;//find the max of d[j] for(j=1;j<i;j++){if(d[j]>max&&a[j]<a[i]&&j<i)max=d[j];}d[i]=max+1;//find the max of d[i]if(d[i]>dmax)dmax=d[i];}printf("%d\n",dmax);return 0;}
(2)最长公共子序列(LCS)问题
POJ1458:
Description
Input
Output
Sample Input
abcfbc abfcabprogramming contest abcd mnp
Sample Output
420
Source
#include<iostream>#include<string>#include<vector>using namespace std;int solve(string s1,string s2){int i,j,len1=s1.size(),len2=s2.size();vector<vector<int>> d(len1+1);for(i=0;i<=len1;i++){vector<int> tmp(len2+1,0);d[i]=tmp;}for(i=0;i<len1;i++)for(j=0;j<len2;j++){if(s1[i]==s2[j])d[i+1][j+1]=d[i][j]+1;elsed[i+1][j+1]=max(d[i+1][j],d[i][j+1]);}return d[len1][len2];}int main(){string s1,s2;while(cin>>s1>>s2){cout<<solve(s1,s2)<<endl;}return 0;}。。。。不贴图了=。=
待续
- 详解动态规划法
- 动态规划详解1
- 动态规划详解2
- 动态规划详解3
- 动态规划详解 第一章
- 动态规划详解I
- 动态规划详解II
- 动态规划详解III
- 动态规划详解
- 详解动态规划算法
- 动态规划详解
- 动态规划详解
- 动态规划详解
- 动态规划详解
- 动态规划入门详解
- 动态规划详解
- 动态规划算法详解
- 动态规划dp详解
- matlab数组元素的引用
- Struts2常量详解
- Surface pro优化工具箱
- 机器学习系列--Naive Bayes Classification
- JSP基础与提高(一)
- 详解动态规划法
- C/C++学习笔记七(内存管理)
- POJ
- 【JavaScript的Math函数和常量】
- Windows安装并使用Celery
- 数据结构栈Stack之中缀表达式转后缀表达式运算应用
- Struts2分模块开发
- springboot创建项目问题:Failure to transfer org.codehaus.plexus:plexus-archiver:jar:2.0.1 from
- POJ