本文主要内容为基础DP,内容来源为《算法导论》,总结不易,转载请注明出处。

  后续会更新出kuanbin关于基础DP的题目......

动态规划:

  动态规划用于子问题重叠的情况,即不同的子问题具有相同的公共子子问题,在这种情况下分治算法会做许多不必要的工作,它会反复求解那些子子问题使得程序边的缓慢。而动态规划则对每个问题 只求解一次,将其解保存在一个表格中,从而避免一些不必要的重复计算。

  动态规划常用来求解最优化问题,这类问题可以有很多解,每个解都有一个值,我们希望寻找具有最优值的解,我们称这样的解为问题的一个最优解,而不是最优解,因为可能有多个最优解。

  动态规划设计算法的一般步骤:

     1.刻画一个最优解的结构特征。

    2.递归的定义最优解的值。

    3.计算最优解的值,通常采用自地向上的方法。

    4.利用计算出的信息构造一个最优解。

  动态规划的两种基本解题步骤:

    第一种为自顶向下法:此方法仍按自然的递归形式编写过程,但过程中会保存每个子问题的解。当需要一个子问题的解时,过程中会首先检查是否此问题已经被求解,如果是则直接返回该解,否则按通常的方式计算,我们称这个递归过程时带备忘的,因为他记住了之前的计算结果,不会进行重复的计算。

    第二种为自底向上法:这种方法一般需要恰当定义子问题的规模的概念,使得任何子问题都只依赖更小的子问题求解。因而我们可以将子问题的规模排序按由小到大的顺序进行求解。当求解某个子问题时,它所依赖的更小的子问题已经得到解决,结果已经保存。每个子问题也只需求解一次。

  最优子结构:

    问题的最优解由相关子问题的最优解构成,这些子问题可以独立求解。

  重构解

    在求解过程中保存相应的状态到另一个辅助数组中即可。

例:钢条切割问题:一根长度为n的钢条,切割不同的长度 i 对应不同的价格p[ i ], 问你如何切割一根钢条使得利益最大化。

  n = i1 + i2 + ... + ik;

  递推式:

    rn = max(pn, r1 + r(n-1), r2 + r(n-2)...r(n-1) +r1)。

  

 #include <iostream>
#include <cstring>
#include <algorithm>
using namespace std; const int maxn = , INF = -0x3f3f3f3f;
long long dp[maxn], s[maxn];
long long p[maxn] = {, , , , , , , , , , };
long long q; long long memoized_cut_rod(int n) {
if(dp[n] >= ) return dp[n];
if(n == ) q = ;
else q = INF;
for(int i = ; i <= n; i ++)
q = max(q, p[i] + memoized_cut_rod(n - i));
dp[n] = q;
return q;
} long long bottom_up_cut_rod(int n) {
dp[] = ;
for(int j = ; j <= n; j ++) {
q = INF;
for(int i = ; i <= j; i ++) {
q = max(q, p[i] + dp[j - i]);
}
dp[j] = q;
}
return dp[n];
} int main () {
long long n;
memset(dp, -, sizeof dp);
while(cin >> n) {
long long ans = memoized_cut_rod(n);
printf("%d\n", ans);
ans = bottom_up_cut_rod(n);
printf("%d\n", ans);
}
}

  重构解:

long long bottom_up_cut_rod(int n) {
dp[] = ;
for(int j = ; j <= n; j ++) {
q = INF;
for(int i = ; i <= j; i ++) {
if(p[i] + dp[j - i] > q) {
q = max(q, p[i] + dp[j - i]);
s[j] = i;
}
}
dp[j] = q;
}
return dp[n];
} while(n) {
cout << s[n] << '\t';
n = n - s[n];
}

例二:求斐波纳挈数

  

#include <iostream>
using namespace std; const int maxn = , INF = 0x3f3f3f3f;
long long dp[maxn]; long long calculate_fib(int n) {
if(n == && n == ) return ;
for(int i = ; i <= n; i ++)
if(dp[i] < ) dp[i] = dp[i - ] + dp[i - ];
return dp[n];
} int main () {
long long n;
for(int i = ; i < maxn; i ++) dp[i] = -INF;
dp[] = dp[] = ;
while(cin >> n) {
cout << calculate_fib(n);
}
}

基础DP(初级版)的更多相关文章

  1. NSIS安装制作基础教程[初级篇], 献给对NSIS有兴趣的初学者

    NSIS安装制作基础教程[初级篇], 献给对NSIS有兴趣的初学者 作者: raindy 来源:http://bbs.hanzify.org/index.php?showtopic=30029 时间: ...

  2. [osg][osgEarth][原]基于OE自定义自由飞行漫游器(初级版)

    由于受够了OE的漫游器,想搞个可以在全球飞行的漫游器,所以就做了一个: 请无视我的起名规则······ 类头文件:EarthWalkManipulator.h #pragma once //南水之源 ...

  3. 我的新书《计算机图形学基础(OpenGL版)》

    我的新书<计算机图形学基础(OpenGL版)>今年6月份在清华大学出版社出版了!新书与原在机械工业出版社出的<计算机图形学>相比,主要有以下不同: 1.加重OpenGL的内容, ...

  4. 02 初级版web框架

    02 初级版web框架 服务器server端python程序(初级版): import socket server=socket.socket() server.bind(("127.0.0 ...

  5. Python之路,Day4 - Python基础4 (new版)

    Python之路,Day4 - Python基础4 (new版)   本节内容 迭代器&生成器 装饰器 Json & pickle 数据序列化 软件目录结构规范 作业:ATM项目开发 ...

  6. 基础dp

    队友的建议,让我去学一学kuangbin的基础dp,在这里小小的整理总结一下吧. 首先我感觉自己还远远不够称为一个dp选手,一是这些题目还远不够,二是定义状态的经验不足.不过这些题目让我在一定程度上加 ...

  7. hdu 5586 Sum 基础dp

    Sum Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Problem Desc ...

  8. 希尔排序之C++实现(初级版)

    希尔排序之C++实现(初级版) 一.源代码:希尔排序之C++实现(初级版) /*希尔排序基本思想: 先取一个小于n的整数d1作为第一个增量,把文件的全部记录分组. 所有距离为d1的倍数的记录放在同一个 ...

  9. 直接插入排序(初级版)之C++实现

    直接插入排序(初级版)之C++实现 一.源代码:InsertSortLow.cpp /*直接插入排序思想: 假设待排序的记录存放在数组R[1..n]中.初始时,R[1]自成1个有序区,无序区为R[2. ...

随机推荐

  1. 【ASP.NET 插件】分享一款富文本web编辑器UEditor

    UEditor是由百度web前端研发部开发所见即所得富文本web编辑器,具有轻量,可定制,注重用户体验等特点,开源基于MIT协议,允许自由使用和修改代码... <%@ Page Language ...

  2. 使用原生js实现前端分页功能

    背景: 从后台提取出来数据,在前端进行分页. 代码: user-manage.js window.onload = function(){ var result = { message : " ...

  3. 采用EntityFramework.Extended 对EF进行扩展

    今天我们来讲讲EntityFramework.Extended 首先科普一下这个EntityFramework.Extended是什么,如下: 这是一个对Entity Framework进行扩展的类库 ...

  4. ACM__搜素之BFS与DFS

    BFS(Breadth_First_Search) DFS(Depth_First_Search) 拿图来说 BFS过程,以1为根节点,1与2,3相连,找到了2,3,继续搜2,2与4,相连,找到了4, ...

  5. linux /dev/null 中有数据

    前段时间有个同事问我说,他 cat /dev/null有数据.这个颠覆大家认知的问题最终却是个小问题. 我们来看/dev/null的操作函数: static const struct memdev { ...

  6. VUE 计算属性 vs 侦听属性

    计算属性 vs 侦听属性 Vue 提供了一种更通用的方式来观察和响应 Vue 实例上的数据变动:侦听属性.当你有一些数据需要随着其它数据变动而变动时,你很容易滥用 watch——特别是如果你之前使用过 ...

  7. 【382】利用 namedtuple 实现函数添加属性

    namedtuple 能够实现类似类的效果,tuple 的元素可以通过属性的形式返回,如下所示: from collections import namedtuple Student = namedt ...

  8. asp.net控件中的reportview不显示

    如果reportview在asp.net中,图标出不来,打X 1.安装reportview控件(在装有vs2010中的电脑中搜,不要去下载,下载可能会出错) 2.如果是iis7以上版本,web.con ...

  9. Linux非常有用的命令

    <判断用户是否存在,如不存在则新建> user=`grep '^admin:' /etc/passwd`if [ -z "$user" ];then groupadd ...

  10. Unity3D初学之2D动画制

    作者:Alex Rose Unity最近宣布推出额外的2D游戏支持,添加了Box 2D物理和一个精灵管理器. 但这里还是有些技巧需要牢记在心.逐帧更改图像只是动画制作的冰山一角,若要让你的游戏出色运行 ...