動態規劃 Dynamic Programming (DP)

Slides:



Advertisements
Similar presentations
渡黑水溝 郁永河. 2 戎克船:是明末清初時期往返兩岸的主要交通工具 ∗ 1. 關於台灣的開發歷史,我們到底了解多少呢?不妨試著說出 就我們所知有關台灣開發史的故事、小說、電影、音樂與大 家分享。 ∗ 2. 什麼是黑水溝?黑水溝為什麼會成為大陸移民渡海來臺時最 大的威脅? ∗ 3. 有聽過「六死三留一回頭」、「有唐山公,無唐山嬤」這兩.
Advertisements

颐高集团项目中心 海亮地产开发模式研究报告. 目 录 目 录 第四部分:海亮地产高周转模式执行 第二部分:海亮地产高周转模式原因 第三部分:海亮地产高周转模式内涵 第一部分:海亮地产企业背景 第五部分:海亮地产高周转支撑体系.
DP 二年级校长助理郭一根设计方案 广东碧桂园( IB )国际学校翻修方案 — 国际部 DP2 年级郭一根.
主讲:王幸民 理学院计算机基础教学部.
今期继续环保驾驶 绿色智慧 24/5/2013 第40期 <环保驾驶2> ISO 办公室
政府採購法規概要 報告人:杜國正 行政院公共工程委員會企劃處.
系统简介 理财顾问 业务 是基于通信平台的技术优势,整合《理财周刊》、第一理财网、乾隆集团等合作伙伴提供的理财产品内容和权威的理财专家资源,以集中式呼叫中心为主的服务方式,让普通百姓可以享受到快捷、全面、专业、权威的资讯及投资理财的服务平台。
之 魔 析 妖 鬼 解 怪 大 沈家仪小组出品.
Dynamic Programming.
宦官那些事儿 宦官那些事儿 主讲:小学部李永善 主讲:小学部李永善.
电视教育课 【5】 小学生行为习惯养成教育.
计算机硕士专业基础—C语言 赵海英
第九章 长期资产及摊销 2017/3/21.
宁波爱地房产市场年报 郊五区
專業成長計畫 教師專業發展評鑑 初階評鑑人員實體研習 蔡惠青 新北市瑞芳高工 (臺北市立麗山國中) 資料來源:
贵宾专享 金融服务方案 邓慧景.
中小學教師專業發展 張德銳 輔仁大學師資培育中心.
糖尿病肾病的护理 陈佳莉.
邁向頂尖大學計畫研究及延攬人才組 (研發處學術發展組) 103年度重點業務推展
奈米溶膠發展的背景介紹 忠信科技 陳忠詰.
高级语言程序设计 主讲人:陈玉华.
物件導向程式設計 (Object-Oriented rogramming)
函數(一) 自訂函數、遞迴函數 綠園.
Phase II: 海报.
Lecture 5 Dynamic Programming
習作2-1 題目+解答 紐約港 紐約中央公園 格陵蘭島.
作弊是否很有诱惑性? 上堂课已经讲了 作业不一定在两个小时里都能完成 答疑没有一个人? 作弊是有记录的 心理系很多同学集体作弊,让人震惊
6 使用者函數 6.1 函數定義 宣告函數 呼叫函數 呼叫多個函數 6-6
柯 維 盈 製 作 (中研院史語所拓片與古文書數位典藏計畫助理)
第五張 方法.
动态规划选讲 JLU – WNJXYK 2018年8月5日.
動態規劃 Dynamic Programming
計數式重複敘述 for 迴圈 P
第七章 轮廓表示 把边缘连接起来就成为轮廓(contour).轮廓可以是断开的,也可以是封闭的. 轮廓可以用边缘有序表或曲线来表示。
第11章 递归 张坤龙 天津大学计算机学院.
C语言复习3----指针.
10465: Homer Simpson ★★★☆☆ 題組:Problem Set Archive with Online Judge
C语言程序设计.
第一章 程序设计和C语言 主讲人:高晓娟 计算机学院.
C语言程序示例: 1.输入10个数,按从小到大的顺序排序。 2.汉诺塔问题。.
C++语言程序设计 C++语言程序设计 第三章 控制语句 第十一组 C++语言程序设计.
陳維魁 博士 儒林圖書公司 第三章 變數與繫結 陳維魁 博士 儒林圖書公司.
C程序设计.
Oop8 function函式.
第八章 指標 (Pointer).
指標
Chap 5 函数 5.1 计算圆柱体积 5.2 使用函数编写程序 5.3 变量与函数.
程式的時間與空間 Time and Space in Programming
均質化計畫形成 與 撰寫及執行經驗分享 光隆家商 楊瑞明
第一章 C语言概述 教师:周芸.
第2章 认识C语言 教学要点 2. 1 项目二C语言程序识读 2 .2 项目三班级成绩排名 2 .3 知识链接 返回.
資料結構與C++程式設計進階 遞迴(Recursion) 講師:林業峻 CSIE, NTU 6/ 17, 2010.
项目1 C程序设计起步 学习目标: 通过该项目你可以知道: C语言的用途。 C语言的基本符号和关键字。 C语言程序的结构及特点。
二分查找的应用 ——李江贝, 郝琰 2017年9月28日.
第二章 类型、对象、运算符和表达式.
生命教育 媒材應用分享 電影 天外奇蹟(UP) 華盛頓高中 巫孟容.
本节内容 函数嵌套调用的内存布局 视频提供:昆山爱达人信息技术有限公司 官网地址: 联系QQ: QQ交流群 : 联系电话:
挑戰C++程式語言 ──第9章 函數.
Dynamic Programming II
遞迴 Recursion.
Computer Science & Information Management
《数据结构与算法设计》第一部分 面向对象的C++程序设计基础.
The role of Algorithms in Computing
05 方法. 05 方法 5.1 方法 在一個較大型的程式中,通常會將具有特定功能或經常重複使用的程式,撰寫成獨立的小單元,稱為「方法」(Method),並賦予方法一個名稱,當程式需要時就可以呼叫此方法來執行該段特定程式。(此種重複使用的程式小單元在其他語言中可能稱為程序、副程式或函式, Visual.
106年度人事業務績效考核績優單位標竿學習分享會
迴圈(重複性結構) for while do while.
判斷(選擇性敘述) if if else else if 條件運算子.
Advanced Competitive Programming
第三章 流程控制 程序的运行流程 选择结构语句 循环结构语句 主讲:李祥 时间:2015年10月.
C++语言程序设计 C++语言程序设计 第二章 基本数据类型与表达式 第十一组 C++语言程序设计.
Presentation transcript:

動態規劃 Dynamic Programming (DP) 101北一女中 資訊選手培訓營 動態規劃 Dynamic Programming (DP) 2012.07.15 Nan

Programming……

Programming @ Math 最佳化問題 Optimization Problem

從切棍子的問題開始

切棍子問題 給你一根棍子,長度為L,你可以任意地把這根棍子切成任意長度的幾段,也可以不切。但不同長度的棍子有不同的價值,要請你算出價值最高的(最佳的)切法。

舉個例子來說 價值如上表,長度為4的棍子有以下8種切法: 把價值高的先切(不切,保留L=4)並不會是最佳解,最佳解是2+2(Value=10) 枚舉所有切的可能性的話,複雜度是指數(就是很大的意思)!

動態規劃法 把大問題切成小問題 (Divide-and-Conquer) 把同樣問題的答案算過後就記下來 決定能算出大問題的小問題是什麼 (最佳子結構) 轉成“遞迴關係” 把同樣問題的答案算過後就記下來

以切棍子來說…… 最佳子結構: 除了最後一段, 在那之前的棍子最大價值(小問題) 最佳子結構: 除了最後一段, 在那之前的棍子最大價值(小問題) 遞迴關係: rod(L) = max 1≤𝑖≤𝐿 (p_i + rod(L – i) ) 𝑖𝑓 𝐿≥1 0 𝑜𝑡ℎ𝑒𝑟𝑤𝑖𝑠𝑒 ; 紀錄: 開一個表格(陣列)紀錄int dp[L];

兩種DP的方式 Bottom-Up (iterative) Top-Down (recursive) 通常直接透過迴圈,表格小的地方開始填,這樣當大的算的時候小的就都填好了。 Top-Down (recursive) 先把表格通通設成像-1之類的值,代表沒填過 之後遞迴呼叫到時,先看看該格是不是-1,不是就回傳該格的值,是就往下遞迴,最後再把值記入該格中。

Bottom-Up解切棍子 int value[L + 1] = {…}; // 各長度的價值 int DP[L + 1]; // 記錄用的表格 int i, j; DP[0] = 0; for ( i = 1 ; i <= L ; i++ ){ DP[i] = 0; for ( j = 1 ; j <= i ; j++ ) if ( DP[i - j] + value[j] > DP[i] ) DP[i] = DP[i – j] + value[j]; }

Top-Down解切棍子 int value[L + 1] = {…}; // 各長度的價值 int DP[L + 1]; // 記錄用的表格 int i, j; void rod_cut(int L){ int i, tmp; if (DP[L] != -1) return DP[L]; DP[L] = 0; for ( i = 1 ; i <= L ; i++ ){ tmp = value[i] + rod_cut(L – i); if ( tmp > DP[L] ) DP[L] = tmp; } int main(){ for ( i = 1 ; i <= L ; i++ ) DP[i] = -1; DP[0] = 0; rod_cut(L);

Bottom-Up解切棍子 大部分時候比較推薦用Bottom-Up! int value[L + 1] = {…}; // 各長度的價值 int DP[L + 1]; // 記錄用的表格 int i, j; DP[0] = 0; for ( i = 1 ; i <= L ; i++ ){ DP[i] = 0; for ( j = 1 ; j <= i ; j++ ) if ( DP[i - j] + value[j] > DP[i] ) DP[i] = DP[i – j] + value[j]; } 大部分時候比較推薦用Bottom-Up!

Maximum Consecutive Sum, MCS 最大連續元素和 Maximum Consecutive Sum, MCS

問題定義 給你一個序列,值可能有正有負。請你算出從哪裡開始到哪裡結束的元素總和最大。

最直覺的想法 直接枚舉「從i開始到j結束」的所有可能性,再把枚舉的起點到終點加起來,找出最大的那個。 O(n3)

DP的作法 最佳子結構: 在元素i之前的MCS為多少。 遞迴關係: 那從加上我也一定會比較大。 我們要的MCS會是過程中算出來 最大的MCS(i)

標準的Bottom-Up DP int ele[N] = {…}; int MCS[N]; int i, max = 0; MCS[0] = ele[0]; for ( i = 1 ; i < N ; i++ ){ if ( MCS[i – 1] < 0 ) MCS[i] = ele[i]; else MCS[i] = MCS[i – 1] + ele[i]; if ( MCS[i] > max ) max = MCS[i]; } printf(“MCS = %d\n”, max);

稍微修改的Bottom-Up DP int ele[N] = {…}; int sum = 0; int i, max = 0; for ( i = 0 ; i < N ; i++ ){ if ( sum < 0 ) sum = 0; sum += ele[i]; if ( sum > max ) max = sum; } printf(“MCS = %d\n”, max); 因為MCS[x]在x+1之後就不用用到, 所以乾脆從頭到尾只用一個變數sum來放就好。

Longest Increasing Subsequence, LIS 最長遞增子序列 Longest Increasing Subsequence, LIS

問題定義 給你一個序列,你必須要從裡面抓出一些元素,形成一子序列(以在原序列的順序排列),且此子序列的元素之間具有遞增關係,長度為所有可能的遞增子序列裡最長的。

DP的作法 最佳子結構: 能接在我之前的元素的LIS是多少 遞迴關係 LIS(i) = max 𝑖>𝑗≥1&&𝑒𝑙𝑒 𝑗 <𝑒𝑙𝑒[𝑖] 𝐿𝐼𝑆 𝑖 +1 找出所有在i之前且能接在i前面的元素j,看看誰的LIS+1最大 跟MCS一樣,我們要的LIS會是過程中算出來最大的LIS(i)

Bottom-Up DP int ele[N] = {…}; int LIS[N]; int i, j, max = 0; for ( i = 0 ; i < N ; i++ ) LIS[i] = 1; // 至少有自己 for ( i = 1 ; i < N ; i++ ){ for ( j = 0 ; j < i ; j++ ){ if ( ele[j] < ele[i] && LIS[j] + 1 > LIS[i] ) LIS[i] = LIS[j] + 1; } if ( LIS[i] > max ) max = LIS[i]; printf(“|LIS| = %d\n”, max); 想想看:這個演算法的複雜度是? 同樣的問題還有更快的作法,但他不能夠“回溯”

LIS的回溯 - 加上一個「我從何而來」的紀錄表格 int ele[N] = {…}; int LIS[N],from[N]; int i, j, max = 0; for ( i = 0 ; i < N ; i++ ){ LIS[i] = 1; // 至少有自己 from[i] = -1; // -1代表從自己來的 } for ( i = 1 ; i < N ; i++ ){ for ( j = 0 ; j < i ; j++ ){ if ( ele[j] < ele[i] && LIS[j] + 1 > LIS[i] ){ LIS[i] = LIS[j + 1]; from[i] = j; if ( LIS[i] > max ) max = LIS[i]; printf(“|LIS| = %d\n”, max);