动态规划例题
- 格式:doc
- 大小:36.00 KB
- 文档页数:2
动态规划的具体应用例题3.1 最长不降子序列(1)问题描述设有由n个不相同的整数组成的数列,记为:a(1)、a(2)、……、a(n)且a(i)<>a(j) (i<>j)例如3,18,7,14,10,12,23,41,16,24。
若存在i1<i2<i3< … < ie 且有a(i1)<a(i2)< … <a(ie)则称为长度为e的不下降序列。
如上例中3,18,23,24就是一个长度为4的不下降序列,同时也有3,7,10,12,16,24长度为6的不下降序列。
程序要求,当原数列给出之后,求出最长的不下降序列。
(2)算法分析根据动态规划的原理,由后往前进行搜索。
1· 对a(n)来说,由于它是最后一个数,所以当从a(n)开始查找时,只存在长度为1的不下降序列;2· 若从a(n-1)开始查找,则存在下面的两种可能性:①若a(n-1)<a(n)则存在长度为2的不下降序列a(n-1),a(n)。
②若a(n-1)>a(n)则存在长度为1的不下降序列a(n-1)或a(n)。
3· 一般若从a(i)开始,此时最长不下降序列应该按下列方法求出: 在a(i+1),a(i+2),…,a(n)中,找出一个比a(i)大的且最长的不下降序列,作为它的后继。
4.用数组b(i),c(i)分别记录点i到n的最长的不降子序列的长度和点i后继接点的编号(3) 程序如下:(逆推法)program li1;const maxn=100;var a,b,c:array[1..maxn] of integer;fname:string;f:text;n,i,j,max,p:integer;beginreadln(fname);assign(f,fname);reset(f);readln(f,n);+for i:=1 to n dobeginread(f,a[i]);b[n]:=1;c[n]:=0;end;for i:= n-1 downto 1 dobeginmax:=0;p:=0;for j:=i+1 to n doif (a[i]<a[j]) and (b[j]>max) then begin max:=b[j];p:=j end;if p<>0 then begin b[i]:=b[p]+1;c[i]:=p endend;max:=0;p:=0;for i:=1 to n doif b[i]>max then begin max:=b[i];p:=i end;writeln('maxlong=',max);write('result is:');while p<>0 dobegin write(a[p]:5);p:=c[p] end;end.3.2 背包问题背包问题有三种1.部分背包问题一个旅行者有一个最多能用m公斤的背包,现在有n种物品,它们的总重量分别是W1,W2,...,Wn,它们的总价值分别为C1,C2,...,Cn.求旅行者能获得最大总价值。
1、单调递增最长子序列描述求一个字符串的最长递增子序列的长度如:dabdbf最长递增子序列就是abdf,长度为4输入第一行一个整数0<n<20,表示有n个字符串要处理随后的n行,每行有一个字符串,该字符串的长度不会超过10000 输出输出字符串的最长递增子序列的长度样例输入3aaaababcabklmncdefg样例输出1372、最长公共子序列描述如题,需要写一个程序,得出最长公共子序列。
tip:最长公共子序列也称作最长公共子串(不要求连续),英文缩写为LCS(Longest Common Subsequence)。
其定义是,一个序列S ,如果分别是两个或多个已知序列的子序列,且是所有符合此条件序列中最长的,则S 称为已知序列的最长公共子序列。
输入第一行给出一个整数N(0<N<100)表示待测数据组数接下来每组数据两行,分别为待测的两组字符串。
每个字符串长度不大于1000.输出每组测试数据输出一个整数,表示最长公共子序列长度。
每组结果占一行。
样例输入2asdfadfsd123abcabc123abc样例输出363、括号匹配时间限制:1000 ms | 内存限制:65535 KB描述给你一个字符串,里面只包含"(",")","[","]"四种符号,请问你需要至少添加多少个括号才能使这些括号匹配起来。
如:[]是匹配的([])[]是匹配的((]是不匹配的([)]是不匹配的输入第一行输入一个正整数N,表示测试数据组数(N<=10)每组测试数据都只有一行,是一个字符串S,S中只包含以上所说的四种字符,S的长度不超过100输出对于每组测试数据都输出一个正整数,表示最少需要添加的括号的数量。
每组测试输出占一行样例输入4[]([])[]((]([)]样例输出324、完全背包描述直接说题意,完全背包定义有N种物品和一个容量为V的背包,每种物品都有无限件可用。
1、单调递增最长子序列描述求一个字符串的最长递增子序列的长度如:dabdbf最长递增子序列就是abdf,长度为4输入第一行一个整数0<n<20,表示有n个字符串要处理随后的n行,每行有一个字符串,该字符串的长度不会超过10000 输出输出字符串的最长递增子序列的长度样例输入3aaaababcabklmncdefg样例输出1372、最长公共子序列描述如题,需要写一个程序,得出最长公共子序列。
tip:最长公共子序列也称作最长公共子串(不要求连续),英文缩写为LCS(Longest Common Subsequence)。
其定义是,一个序列S ,如果分别是两个或多个已知序列的子序列,且是所有符合此条件序列中最长的,则S 称为已知序列的最长公共子序列。
输入第一行给出一个整数N(0<N<100)表示待测数据组数接下来每组数据两行,分别为待测的两组字符串。
每个字符串长度不大于1000.输出每组测试数据输出一个整数,表示最长公共子序列长度。
每组结果占一行。
样例输入2asdfadfsd123abcabc123abc样例输出363、括号匹配时间限制:1000 ms | 内存限制:65535 KB描述给你一个字符串,里面只包含"(",")","[","]"四种符号,请问你需要至少添加多少个括号才能使这些括号匹配起来。
如:[]是匹配的([])[]是匹配的((]是不匹配的([)]是不匹配的输入第一行输入一个正整数N,表示测试数据组数(N<=10)每组测试数据都只有一行,是一个字符串S,S中只包含以上所说的四种字符,S的长度不超过100输出对于每组测试数据都输出一个正整数,表示最少需要添加的括号的数量。
每组测试输出占一行样例输入4[]([])[]((]([)]样例输出324、完全背包描述直接说题意,完全背包定义有N种物品和一个容量为V的背包,每种物品都有无限件可用。
23.(11分)请用动态规划逆序求解法求解下列问题:求出下图中从A到E的最短路线及长度。
在图中标出每个点到终点的最短距离。
24. (11分)一个旅行者从A点出发,经过B、C、D等处,到达E。
各地间距离如图中所示。
问该旅行者应选择哪一条路线,使从A到E的总路程最短?(可直接在图上标号,最后给定答案)
24.一个旅行者从A点出发,经过B、C、D等处,到达E。
各地间距离如图中所示。
问该旅行者应选择哪一条路线,使从A到E的总路程最短?(可直接在图上标号,最后给定答案)(11分)
解:此为动态规划之“最短路问题”,可用逆向追踪“图上标号法”解决如下:
最佳策略为:A →B 2→C 1→D 1→E 或A →B 3→C 1→D 1→E 此时从A 到E 的总路程的最短距离都是11
23. 请用动态规划逆序求解法求解下列问题:
各点标号依次为:A:8, B1:7,B2:6, B3:8, C1:5, C2:4,D1:3,D2:1,D3:5.
25. 某厂生产C B A ,,三种产品,其所需劳动力、材料等有关数据见下表。
要求:建立模型,并用单纯形法计算,确定获利最大的产品生产计划。
解:(1)设C B A ,,
各生产321,,x x x 件。
有
32143min x x x z ++=
st.⎪⎩⎪
⎨⎧=≥≤++≤++)3,2,1(,03054345
536321321j x x x x x x x j
(4分)
获利最大的生产计划是C B A ,,各生产5件、0件、3件,最大利润为273453=⨯+⨯=z 元。
(15分)。
1
第五章 动态规划作业题及答案
1.用动态规划法求解求最短路径
从起点A 到终点E 之间各点的距离如图所示。
求A 到E 的最短路径。
B A
C B
D B C D E
C 21
23
12
31
2
5
11214
10610
41312113
96
5810
5
2
2.用动态规划法求解资源分配问题
有资金4万元,投资A 、B 、C 三个项目,每个项目的投资效益与投入该项目的资金有关。
三个项目A 、B 、C 的投资效益(万吨)和投入资金(万元)的关系见下表:
用动态规划法求解对三个项目的最优投资分配,使总投资效益最大。
3.用动态规划法求解生产库存问题
一个工厂生产某种产品,1~7月份生产成本和产品需求量的变化情况如下表:
为了调节生产生产和需求,工厂设有一个产品仓库,库容量H=9。
已知期初库存量为2,要求期末(七月低)库存量为0。
每个月生产的产品在月末入库,月初根据当月需求发货。
求七个月的生产量,能满足各月的需求,并使生产成本最低。
4.用动态规划法求解背包问题
第i 种每件价值c 1=65,c 2=85,c 3=40元; 第i 种物品每件重量为:w 1=2,w 2=3,w 3=1公斤;现有一只可装载重量为5公斤的背包,求各种物品应各取多少件放入背包,使背包中物品的价值最高。
动态规划总结1.POJ 1160Post OfficeTime Limit: 1000MS Memory Limit: 10000KTotal Submissions: 17936 Accepted: 9655DescriptionThere is a straight highway with villages alongside the highway. The highway is represented as an integer axis, and the position of each village is identified with a single integer coordinate. There are no two villages in the same position. The distance between two positions is the absolute value of the difference of their integer coordinates.Post offices will be built in some, but not necessarily all of the villages. A village and the post office in it have the same position. For building the post offices, their positions should be chosen so that the total sum of all distances between each village and its nearest post office is minimum.You are to write a program which, given the positions of the villages and the number of post offices, computes the leastpossible sum of all distances between each village and its nearest post office.IntputYour program is to read from standard input. The first line contains two integers: the first is the number of villages V, 1 <= V <= 300, and the second is the number of post offices P, 1 <= P <= 30, P <= V. The second line contains V integers in increasing order. These V integers are the positions of the villages. For each position X it holds that 1 <= X <= 10000. outputThe first line contains one integer S, which is the sum of all distances between each village and its nearest post office. Sample input10 51 2 3 6 7 9 11 22 44 50Sample output9题目大意:用数轴描述一条高速公路,有V个村庄,每一个村庄坐落在数轴的某个点上,需要选择P个村庄在其中建立邮局,要求每个村庄到最近邮局的距离和最小。
动态规划应用案例动态规划是一种解决复杂问题的优化算法。
它通过将问题拆分成多个子问题,并记录每个子问题的解,以避免重复计算,从而提高算法的效率。
在实际应用中,动态规划被广泛用于解决各种问题,包括最优化问题、路径搜索问题、序列问题等。
本文将介绍几个动态规划的应用案例,以展示其在实际问题中的强大能力。
案例一:背包问题背包问题是动态规划中经典的一个例子。
假设有一个背包,容量为V,现有n个物品,每个物品的重量为wi,价值为vi。
要求在不超过背包容量的前提下,选取一些物品放入背包,使得背包中的物品总价值最大。
这个问题可以用动态规划来解决。
首先定义一个二维数组dp,其中dp[i][j]表示在前i个物品中选择一些物品,使得它们的总重量不超过j时的最大总价值。
然后,可以得到如下的状态转移方程:dp[i][j] = max(dp[i-1][j], dp[i-1][j-wi] + vi)最后,根据状态转移方程,可以循环计算出dp[n][V]的值,即背包中物品总价值的最大值,从而解决了背包问题。
案例二:最长递增子序列最长递增子序列是指在一个序列中,选取一些数字,使得这些数字按照顺序排列,且长度最长。
动态规划也可以应用于解决最长递增子序列问题。
假设有一个序列nums,长度为n。
定义一个一维数组dp,其中dp[i]表示以nums[i]为结尾的最长递增子序列的长度。
然后,可以得到如下的状态转移方程:dp[i] = max(dp[j] + 1),其中j < i且nums[j] < nums[i]最后,循环计算出dp数组中的最大值,即为最长递增子序列的长度。
案例三:最大子数组和最大子数组和问题是指在一个数组中,选取一段连续的子数组,使得子数组的和最大。
动态规划也可以用于解决最大子数组和问题。
假设有一个数组nums,长度为n。
定义一个一维数组dp,其中dp[i]表示以nums[i]为结尾的连续子数组的最大和。
然后,可以得到如下的状态转移方程:dp[i] = max(dp[i-1] + nums[i], nums[i])最后,循环计算出dp数组中的最大值,即为最大子数组的和。
动态规划入门练习题1.石子合并在一个圆形操场的四周摆放着N堆石子(N<= 100),现要将石子有次序地合并成一堆.规定每次只能选取相邻的两堆合并成新的一堆,并将新的一堆的石子数,记为该次合并的得分.编一程序,由文件读入堆栈数N及每堆栈的石子数(<=20).(1)选择一种合并石子的方案,使用权得做N-1次合并,得分的总和最小;(2)选择一种合并石子的方案,使用权得做N-1次合并,得分的总和最大;输入数据:第一行为石子堆数N;第二行为每堆的石子数,每两个数之间用一个空格分隔.输出数据:从第一至第N行为得分最小的合并方案.第N+1行是空行.从第N+2行到第2N+1行是得分最大合并方案.每种合并方案用N行表示,其中第i行(1<=i<=N)表示第i次合并前各堆的石子数(依顺时针次序输出,哪一堆先输出均可).要求将待合并的两堆石子数以相应的负数表示.输入输出范例:输入:44 5 9 4输出:-459-4-8-59-13-9224-5-944-14-4-4-1822最小代价子母树设有一排数,共n个,例如:22 14 7 13 26 15 11.任意2个相邻的数可以进行归并,归并的代价为该两个数的和,经过不断的归并,最后归为一堆,而全部归并代价的和称为总代价,给出一种归并算法,使总代价为最小.输入、输出数据格式与“石子合并”相同。
输入样例:412 5 16 4输出样例:-12-516417-16-4-17-20372.背包问题设有n种物品,每种物品有一个重量及一个价值。
但每种物品的数量是无限的,同时有一个背包,最大载重量为XK,今从n种物品中选取若干件(同一种物品可以多次选取),使其重量的和小于等于XK,而价值的和为最大。
输入数据:第一行两个数:物品总数N,背包载重量XK;两个数用空格分隔;第二行N个数,为N种物品重量;两个数用空格分隔;第三行N个数,为N种物品价值; 两个数用空格分隔;输出数据:第一行总价值;以下N行,每行两个数,分别为选取物品的编号及数量;输入样例:4 102 3 4 71 3 5 9输出样例:122 14 13.商店购物某商店中每种商品都有一个价格。
动态规划经典例题动态规划关键在于填表以及输出过程(个⼈理解)算法思想把原问题分解成若⼲个简单的⼦问题,保存已解决的⼦问题答案,避免重复计算。
动态规划常应⽤于有重叠⼦问题和最优⼦结构性质的问题。
⼦问题最优从⽽达到全局最优。
算法基本步骤找出最优解的性质递归的定义最优值以⾃底向上的⽅式计算最优值根据计算最优值的信息构造最优解经典案例⼀ 0/1背包问题import java.util.Scanner;import static sun.misc.Version.println;public class Dp{int n,v;//物品数量和容积int value[];int weight[];int dp[][];//dp[i][j]表⽰i个物品,容积为j时得到的最⼤价值public void Maxvalue(){for(int i=1;i<=n;i++){for(int j=0;j<=v;j++){//注意下标还有别的写法if(j>=weight[i]){dp[i][j]=Math.max(value[i]+dp[i-1][j-weight[i]], //拿了第i个dp[i-1][j]);//没拿}else{dp[i][j]=dp[i-1][j];}}}for(int i=0;i<=n;i++){for(int j=0;j<=v;j++){System.out.print(dp[i][j] + " ");}System.out.println();}}public void BestResult(int n,int v){boolean isAdd[]=new boolean[n+1];//记录物品是否拿了for(int i=n;i>=1;i--){ // 倒序if(dp[i][v]==dp[i-1][v]){isAdd[i]=false;}else{isAdd[i]=true;}v-=weight[i];}for(int i=1;i<=n;i++){//把结果正序输出System.out.println(i+"是"+isAdd[i]);}}public void Init(){Scanner sc =new Scanner (System.in);n=sc.nextInt();v=sc.nextInt();weight=new int [n+1];value=new int [n+1];dp=new int[n][v];for(int i=1;i<=n;i++){weight[i]=sc.nextInt();}for(int i=1;i<=n;i++){value[i]=sc.nextInt();}}public static void main(String[] args){Dp bag=new Dp();bag.Init();bag.Maxvalue();bag.BestResult(bag.n,bag.v);}}经典例题⼆矩阵连乘问题public class dp_matrix {int j=6;int p[];int s[][];//记录断点kint dp[][];//最⼩代价public dp_matrix() {p=new int[]{10,15,25,35,20,10,40};s=new int[j][j];dp=new int[j][j];}public void dp_matrix(){for(int i=0;i<j;i++){dp[i][i]=0;}for(int r=2;r<=j;r++){for(int i=0;i<=j-r;i++){int n=i+r-1;dp[i][n]=dp[i+1][n]+p[i]*p[i+1]*p[n+1];//i<js[i][n]=i;//在i+1分的for(int k=i+1;k<n;k++){int key=dp[i][k]+dp[k+1][n]+p[i]*p[k+1]*p[n];//注意下标if(key<dp[i][n]){dp[i][n]=key;//更新s[i][n]=k;// 更新}}}}}public void traceBack(int i ,int j){if(i==j){System.out.print(i);}else{System.out.print("(");traceBack(i,s[i][j]);traceBack(s[i][j]+1,j);System.out.print(")");}}public static void main(String[] args){dp_matrix matrix=new dp_matrix();matrix.dp_matrix();matrix.traceBack(0,5);}}经典例题三最长公共⼦序列public class Dp_Lcs {public void Maxlength(){String []m={"a","b","c","d"};String []n={"b","c","d"};int x=m.length;int y=n.length;int [][] dp=new int[m.length+1][n.length+1];//dp[i][j]表⽰xi与yi两个序列最长公共⼦序列的长度 int[][] s=new int[m.length][n.length];//s[i][j]⽤来储存m[i]与n[j]之间的关系for(int i=0;i<=x;i++){//初始化dp[i][0]=0;}for(int i=0;i<=y;i++){dp[0][i]=0;}for(int i=1;i<=x;i++){for(int j=1;j<=y;j++){if(m[i-1]==(n[j-1])){ //相等时dp[i][j]=dp[i-1][j-1]+1;//参照图s[i-1][j-1]=1;}else {dp[i][j]=Math.max(dp[i-1][j], dp[i][j-1]);if(dp[i][j]==dp[i-1][j]){s[i-1][j-1]=-1;}else s[i-1][j-1]=0;}}}for(int i=0;i<x;i++){for(int j=0;j<y;j++){System.out.print(s[i][j]);}System.out.println();}for(int i=0;i<x+1;i++){for(int j=0;j<y+1;j++){System.out.print(dp[i][j]);}System.out.println();}System.out.println("最长为"+" ");LCS(s,m,x,y);}public void LCS(int[][] s, String[] m, int i, int j){//{递归遍历s[i][j]if(i == 0 || j == 0){ return;}switch (s[i-1][j-1]) {case 1:LCS(s,m,i - 1, j - 1);System.out.println(m[i-1]+ " ");break;case 0:LCS(s,m,i - 2, j);break;default:LCS(s,m,i, j-2);break;}}public static void main(String[] args) { Dp_Lcs a=new Dp_Lcs();a.Maxlength();}}。
动态规划算法题(5题)1、题⽬描述(⽹易)有 n 个学⽣站成⼀排,每个学⽣有⼀个能⼒值,⽜⽜想从这 n 个学⽣中按照顺序选取 k 名学⽣,要求相邻两个学⽣的位置编号的差不超过d,使得这 k 个学⽣的能⼒值的乘积最⼤,你能返回最⼤的乘积吗?输⼊描述:每个输⼊包含 1 个测试⽤例。
每个测试数据的第⼀⾏包含⼀个整数 n (1 <= n <= 50),表⽰学⽣的个数,接下来的⼀⾏,包含 n 个整数,按顺序表⽰每个学⽣的能⼒值 ai(-50 <= ai <= 50)。
接下来的⼀⾏包含两个整数,k 和 d (1 <= k <= 10, 1 <= d <= 50)。
输出描述:输出⼀⾏表⽰最⼤的乘积。
试题分析:本题要使⽤动态规划来解,动态规划的特点:1.求解的是最优化问题;2.可以分解为最优⼦结构本题可以先求解在第i个学⽣的位置下,j(j<K)个学⽣的能⼒值的最⼤值,得到所有学⽣位置下j个学⽣的能⼒值的最⼤值;在j个学⽣的情况下,得到j+1个学⽣的最⼤值,样例输出: 10 8 7 2 -7 9 5 4 10 -7 1 3 3输出: 630如上,第⼀步先计算k=2的情况:7:在d=3的情况下,最⼤最⼩值都为562:在d=3的情况下,最⼤值为16,最⼩值为14-7:在d=3的情况下,最⼤值为-14,最⼩值为-56......得到第⼀趟的结果k=3的情况下(这⾥以第⼀趟的结果为基础,只有这样就不需要考虑第⼀趟中d=3的限制):2:在d=3的情况下,最⼤最⼩值都为112(56*2)-7:在d=3的情况下,最⼤值为-98(14*-7)最⼩值为-392(56*-7)9:在d=3的情况下,最⼤值为504(56*9)最⼩值为-504(-56*9)......得到第⼆趟的结果返回最⼤值就是最后的结果#-*- coding:utf-8 -*-n=input()array=[int(i) for i in raw_input().split()]k,d=[int(i) for i in raw_input().split()]# n=36array_max=array_min=array#轮询k-1趟即可for i in range(0,k-1):_max=[-float('inf')]*n#将最⼤值的数组赋值⽆穷⼩_min=[float('inf')]*n#将最⼩值的数组赋值⽆穷⼤for j in range(i+1,n):if j<=d+i:#下⾯对应的min、max都是考虑到array[j]为负值的情况下temp_max = max(max(ii*array[j] for ii in array_max[i:j]),max(ii*array[j] for ii in array_min[i:j]))temp_min = min(min(ii*array[j] for ii in array_max[i:j]),min(ii*array[j] for ii in array_min[i:j]))else:temp_max = max(max(ii*array[j] for ii in array_max[j-d:j]),max(ii*array[j] for ii in array_min[j-d:j]))temp_min = min(min(ii*array[j] for ii in array_max[j-d:j]),min(ii*array[j] for ii in array_min[j-d:j]))_max[j]=temp_max_min[j]=temp_minarray_max=_maxarray_min=_minprint array_maxprint array_minprint max(array_max)2、题⽬描述(腾讯):腾讯⼤厦有39层,你⼿⾥有两颗⼀抹⼀眼的玻璃珠。
例1 求解下列整数规划得最优解:()123123max 45634510..01,2,3,j j Z x x x x x x s t x j x =++++⎧⎪⎨=⎪⎩≤≥为整数.解 (1)建立动态规划模型:阶段变量: 将给每一个变量 赋值瞧成一个阶段, 划分为3个阶段, 且阶段变量k=1,2,3. 设状态变量 表示从第 阶段到第3阶段约束右端最大值, 则 设决策变量k x 表示第k 阶段赋给变量k x 得值(1,2,3)k =、 状态转移方程: 阶段指标: 基本方程;()(){}()3113,2,1044()max ,()0.s k k k k k k k k k k x a f s u s x f s f s ++⎡⎤=⎢⎥⎢⎥⎣⎦⎧=+⎪⎨⎪=⎩≤≤ 其中1233,4, 5.a a a === 用逆序法求解: 当3k =时,()(){}{}33333443330055max 6max 6,ssx x f s x f s x ⎡⎤⎡⎤⎢⎥⎢⎥⎢⎥⎢⎥⎣⎦⎣⎦=+=≤≤≤而 表示不超过 得最大整数。
因此, 当 时, ;当 时, 可取0或1;当 时, 可取0, 1, 2,由此确定 现将有关数据列入表4.1中当 时, 有()(){}(){}22222332322220044max 5max 54,ssx x f s xf s xf s x ⎡⎤⎡⎤⎢⎥⎢⎥⎢⎥⎢⎥⎣⎦⎣⎦=+=+-≤≤≤≤而 。
所以当 时, ;当 时, ;当 时 。
由此确定 。
现将有关数据列入表4.2中、当时,有()(){}(){}11111221211110033max 4max 43,ssx x f s x f s x f s x ⎡⎤⎡⎤⎢⎥⎢⎥⎢⎥⎢⎥⎣⎦⎣⎦=+=+-≤≤≤≤例5 用动态规划方法解下列非线性规划问题⎩⎨⎧=≥≤++⋅⋅=3,2,1 0 max 3213221i x c x x x x x x z i 解: 解决这一类静态规划问题, 需要人为地赋予时间概念, 从而将该问题转化为多阶段决策过程。
动态规划题目【引例1、上楼梯】一个含有n阶的楼梯,一次可以走1阶或2阶,从底走到顶一共有几种走法?n<=90。
【引例2、数字三角形】a1有一个数字三角形,编程求从最顶层到最底层的一条路所经过位置上数字之和的最大值。
每一步只能向左下或右下方向走。
下图数据的路应为7->3->8->7->5,和为30。
输入:文件输入(从键盘读入文件名),文件格式:第一行:R(1<=R<=10000),数字三角形共有R行;以下R行:依次表示数字三角形中每行中的数字。
每个数都是非负的,且<=100.输出:一个正整数,路径上数字之和的最大值。
输入样例:573 88 1 02 7 4 44 5 2 6 5输出样例:30【引例3、求最大连续子序列的和。
】a2输入:第一行:n(N<500)第二行:n个整数(-3000,3000)。
输出:最大连续子序列的和。
样例:输入:7-6 4 -1 3 2 -3 2输出:81、最长递增序列b1设有整数序列b1,b2,b3,…,bm,若存在i1<i2<i3<…<in,且bi1<bi2<bi3<…<bin,则称b1,b2,b3,…,bm 中有长度为n的递增序列bi1,bi2,bi3,…,bin。
求序列b1,b2,b3,…,bm中最大递增序列长度(n)。
输入:m(<1000),整数序列输出:最大长度n样例:输入:7-6 4 -1 3 8 -3 2输出:42、背包问题b2设有n种物品,每种物品有一个重量及一个价值。
同时有一个背包,最大载重量为W,今从n种物品中选取若干件,使其重量的和小于等于W,而价值的和为最大。
输入数据:第一行两个数:物品总数N(<100),背包载重量W(<100);两个数用空格分隔;第二行N个数,为N种物品重量Wi;两个数用空格分隔;第三行N个数,为N种物品价值Vi; 两个数用空格分隔;输出数据:第一行总价值;输入样例:4 103 4 5 77 15 20 25输出样例:353、迷宫寻宝b3一个n行m列的迷宫(1<=n,m<=50),入口在左上角,规定只能向下或向右走。
动态规划练习题USACO 2.2 Subset Sums题目如下:对于从1到N的连续整集合合,能划分成两个子集合,且保证每个集合的数字和是相等的。
举个例子,如果N=3,对于{1,2,3}能划分成两个子集合,他们每个的所有数字和是相等的:and {1,2}这是唯一一种分发(交换集合位置被认为是同一种划分方案,因此不会增加划分方案总数)如果N=7,有四种方法能划分集合{1,2,3,4,5,6,7},每一种分发的子集合各数字和是相等的:{1,6,7} and {2,3,4,5} {注1+6+7=2+3+4+5}{2,5,7} and {1,3,4,6}{3,4,7} and {1,2,5,6}{1,2,4,7} and {3,5,6}给出N,你的程序应该输出划分方案总数,如果不存在这样的划分方案,则输出0。
程序不能预存结果直接输出。
PROGRAM NAME: subsetINPUT FORMAT输入文件只有一行,且只有一个整数NSAMPLE INPUT (file subset.in)7OUTPUT FORMAT输出划分方案总数,如果不存在则输出0。
SAMPLE OUTPUT (file subset.out)4参考程序如下:#include <fstream>using namespace std;const unsigned int MAX_SUM = 1024;int n;unsigned long long int dyn[MAX_SUM];ifstream fin ("subset.in");ofstream fout ("subset.out");int main() {fin >> n;fin.close();int s = n*(n+1);if (s % 4) {fout << 0 << endl;fout.close ();return ;}s /= 4;int i, j;dyn [0] = 1;for (i = 1; i <= n; i++)for (j = s; j >= i; j--)dyn[j] += dyn[j-i];fout << (dyn[s]/2) << endl;fout.close();return 0;}USACO 2.3 Longest Prefix题目如下:在生物学中,一些生物的结构是用包含其要素的大写字母序列来表示的。
习题6-1. 考虑下面的网络图,箭头上的数字代表相连两个节点之间的距离。
(1)用动态规划找出从节点1到节点10的最短路。
(2)从节点4到节点10的最短路呢?6-2. 从北京到上海的包机的剩余装载能力为2000kg ,某一运输公司现有4种货物需要从北京运输到上海。
每种货物的单位、单位重量和单位运输费用如下表所示。
(1)用动态规划找出包机应该运输的每种货物的单位数。
(2)假设包机同意装载另一批货物,剩余装载能力降为1800kg ,计算结果会怎样变化?6-3. 假定有一个3阶段的过程,每一阶段的产量是需要做出决策的函数。
使用数学符号,问题表述如下:Max ()()()332211d r d r d r ++ s.t.1000321≤++d d d 每个阶段的决策变量和相应的返回值如下所示:6-4. 某制造公司为一家汽车工厂提供发动机的部件,以下是3个月的生产计划的数据。
量是10单位,并且生产批量是10的倍数(例如,10,20或者30单位)。
6-5. 某物流公司雇佣了8名新员工,现决定如何把他们分配到4项作业上。
公司给出了以下每项作业分配不同的作业人员的估计利润表。
(1) 用动态规划决定每项作业应该分配的新员工数目。
(2) 如果公司只雇佣了6名新员工,应该把这些员工分配给哪些作业?6-6. 一个锯木厂采购了一批20ft 长的原木,想要把这些原木切成更短的原木,然后把切后的小原木卖给制造公司。
制造公司已经订购了一批4种尺寸的原木:l 1=3ft ,l 2=7ft ,l 3=11ft ,l 4=16ft 。
锯木厂现在有2000个长度为20ft 的原木的库存,并希望有选择地裁截原木以最大化利润。
假定锯木厂的订单是无限的,唯一的问题就是确定把现有原木裁成的类型以最大化利润。
原木的利润如下表所示:任何裁截类型的长度限制如下:201173321≤++d d d 其中,i d 是长度为i l 的类型的裁截数目,4,3,2,1=i .(1)为这个问题建立动态规划模型,并使用模型解决问题。
动态规划题目动态规划(Dynamic Programming)是一种常用的求解最优化问题的方法。
它的核心思想是,将问题拆解成若干个子问题,并保存子问题的解,以便后续计算。
通过利用子问题的解,逐步求得原问题的最优解。
一个典型的动态规划问题可以用一个简单的例子来说明。
假设有一段长度为n的绳子,我们希望将它切割成若干段,使得乘积最大。
例如,当n=8时,我们可以切割成长度为2、3和3的三段,此时乘积最大,为18。
这个问题可以用动态规划来解决。
首先,我们定义一个数组dp,其中dp[i]表示长度为i的绳子的乘积最大值。
显然,dp[0]=0,dp[1]=1,dp[2]=2,dp[3]=3。
然后,我们需要考虑长度大于3的情况。
对于长度为i的绳子,我们可以将其切割成两段,长度为j和i-j。
那么,长度为i的绳子的乘积最大值可以表示为dp[j]*dp[i-j]。
然后我们需要遍历所有可能的j的值,找出其中的最大值,作为dp[i]的值。
具体的计算过程如下所示:for i from 4 to n:for j from 1 to i/2:dp[i] = max(dp[i], dp[j]*dp[i-j])最后,返回dp[n]即为所求的最大乘积。
动态规划的核心思想就是将问题拆解成子问题,并保存子问题的解,以便后续计算。
在上述例子中,我们将长度为n的绳子切割成长度为j和i-j的两段,然后计算乘积最大值。
这里的子问题是求解长度为j和长度为i-j的绳子的乘积最大值,因此可以利用dp数组保存子问题的解。
动态规划的时间复杂度和空间复杂度由问题的规模决定。
在上述例子中,我们需要计算长度为n的绳子的最大乘积,需要进行两层循环遍历,因此时间复杂度为O(n^2)。
空间复杂度则由dp数组决定,为O(n)。
动态规划是一种非常常见且有效的求解最优化问题的方法。
通过将问题拆解成若干个子问题,并保存子问题的解,可以大大优化问题的求解过程。
在实际应用中,我们可以通过改变子问题的定义和状态转移方程,来解决不同的问题。
例1:机器负荷分配问题
某公司新购进1000台机床,每台机床都可在高、低两种不同的负荷下进行生产,设在高负荷下生产的产量函数为g(x )=10x (单位:百件),其中x 为投入生产的机床数量,年完好率为a =0.7;在低负荷下生产的产量函数为h(y)=6y (单位:百件),其中y 为投人生产的机床数量,年完好率为b=0.9。
计划连续使用5年,试问每年如何安排机床在高、低负荷下的生产计划,使在五年内生产的产品总产量达到最高。
例2:某企业通过市场调查,估计今后四个时期市场对某种产品的需要量如下表:
时期(k) 1
2 3 4 需要量(d k )
2(单位)
3
2
4
假定不论在任何时期,生产每批产品的固定成本费为3(千元),若不生产,则为零;生产单位产品成本费为1(千元);每个时期生产能力所允许的最大生产批量为不超过6个单位,则任何时期生产x 个单位产品的成本费用为:
若 0<x ≤6 , 则生产总成本=3十1·x 若 x =0 , 则生产总成本=0
又设每个时期末未销售出去的产品,在一个时期内单位产品的库存费用为0.5(千元),同时还假定第1时期开始之初和在第4个时期之末,均无产品库存。
现在我们的问题是;在满足上述给定的条件下,该厂如何安排各个时期的生产与库存,使所花的总成本费用最低?
例3:设某企业在第一年初购买一台新设备,该设备在五年内的年运行收益、年运行费用及更换新设备的净费用如下表:(单位:万元)
年份(k) 役龄(t) 运行收益()k g t 运行费用()k r t 更新费用()k c t 第一年 0 22 6 18 第二年
0 1
23 21
6 8
19 22
第三年0
1
2
23
21
18
5
7
10
19
23
28
第四年0
1
2
3
24
22
19
16
5
7
10
15
20
24
30
38
第五年0
1
2
3
4
25
23
20
17
14
4
6
9
14
20
20
24
30
38
48
试为该企业制定一个五年中的设备更新策略,使得企业在五年内总收益达到最大?
例4:设有一辆栽重为10吨的卡车,用以装载三种货物,每种货物的单位重量及单件价值如表所示,问各种货物应装多少件,才能既不超过总重量又使总价值最大?
货物 1 2 3
单位重量 3 4 5
单件价值 4 5 6。