动态规划状态转移方程
leetcode常见dp题状态转移方程

Leetcode常见DP题状态转移方程一、概述动态规划(Dynamic Programming, DP)是算法设计中的一种常用方法,它通常用于优化递归算法,解决重叠子问题。
Leetcode上有许多经典动态规划问题,而理解状态转移方程是解决这些问题的关键。
本文旨在总结Leetcode常见DP题的状态转移方程,帮助读者更好地理解和掌握动态规划算法的应用。
二、背包问题1. 0-1背包问题问题描述:给定一组物品,每种物品都有重量和价值,要求在限定的总重量下,如何使得所装载的物品总价值最高。
状态转移方程:```dp[i][j] = max(dp[i-1][j], dp[i-1][j-weight[i]] + value[i]), 1 <= i <= n, 1 <= j <= C```其中,dp[i][j]表示前i个物品中最大重量不超过j时的最大价值,weight[i]表示第i个物品的重量,value[i]表示第i个物品的价值,C 表示背包的容量,n为物品的个数。
2. 完全背包问题问题描述:给定一组物品,每种物品都有重量和价值,每种物品不限数量,要求在限定的总重量下,如何使得所装载的物品总价值最高。
状态转移方程:```dp[i][j] = max(dp[i-1][j], dp[i][j-weight[i]] + value[i]), 1 <= i <= n, 1 <= j <= C```其中,dp[i][j]表示前i个物品中最大重量不超过j时的最大价值,weight[i]表示第i个物品的重量,value[i]表示第i个物品的价值,C 表示背包的容量,n为物品的个数。
3. 多重背包问题问题描述:给定一组物品,每种物品都有重量和价值,每种物品有限数量,要求在限定的总重量下,如何使得所装载的物品总价值最高。
状态转移方程:```dp[i][j] = max(dp[i-1][j], dp[i-1][j-k*weight[i]] + k*value[i]), 1 <= i <= n, 1 <= j <= C, 0 <= k <= num[i]```其中,dp[i][j]表示前i个物品中最大重量不超过j时的最大价值,weight[i]表示第i个物品的重量,value[i]表示第i个物品的价值,num[i]表示第i个物品的数量,C表示背包的容量,n为物品的个数。
爬楼梯问题的解题技巧

爬楼梯问题的解题技巧爬楼梯问题是在计算机科学和数学领域经常遇到的一个经典问题。
题目描述如下:假设你正在爬楼梯,楼梯有n级台阶。
每次你可以爬1级台阶或者2级台阶。
请问,你有多少种不同的方法可以爬到楼梯顶部?这个问题可以用递归和动态规划两种方法来解决。
下面我将分别介绍这两种解题技巧。
1. 递归解法:递归解法是最直观的解法,通过将问题分解成更小的子问题来解决。
假设爬到第n级台阶有f(n)种方法,那么可以得到以下递推关系:f(n) = f(n-1) + f(n-2)。
也就是说,爬到第n级台阶的方法数等于爬到第n-1级台阶的方法数加上爬到第n-2级台阶的方法数。
递归解法的代码如下:```pythondef climbStairs(n):if n == 1:return 1if n == 2:return 2return climbStairs(n-1) + climbStairs(n-2)```递归解法的时间复杂度为O(2^n),因为在每一级台阶上都有两种选择,所以递归树的节点数为指数级别。
虽然递归解法的代码简洁,但是对于大规模的问题,会导致指数级别的计算量,效率较低。
2. 动态规划解法:动态规划是一种将复杂问题分解成简单子问题的解决方法,通过保存子问题的解来避免重复计算,从而提高效率。
对于爬楼梯问题,可以使用动态规划来解决。
我们可以定义一个长度为n+1的数组dp,其中dp[i]表示爬到第i级台阶的方法数。
根据递推关系f(n) = f(n-1) + f(n-2),可以得到动态规划的状态转移方程:dp[i] = dp[i-1] + dp[i-2]。
初始条件为dp[1] = 1,dp[2] = 2。
动态规划解法的代码如下:```pythondef climbStairs(n):dp = [0] * (n+1)dp[1] = 1dp[2] = 2for i in range(3, n+1):dp[i] = dp[i-1] + dp[i-2]return dp[n]```动态规划解法的时间复杂度为O(n),因为只需计算n个状态,每个状态的计算只需要常数时间。
动态规划状态转移方程

1.资源问题1-----机器分配问题F[I,j]:=max(f[i-1,k]+w[i,j-k])2.资源问题2------01背包问题F[I,j]:=max(f[i-1,j-v[i]]+w[i],f[i-1,j]);3.线性动态规划1-----朴素最长非降子序列F[i]:=max{f[j]+1}4.剖分问题1-----石子合并F[i,j]:=min(f[i,k]+f[k+1,j]+sum[i,j]);5.剖分问题2-----多边形剖分F[I,j]:=min(f[i,k]+f[k,j]+a[k]*a[j]*a[i]);6.剖分问题3------乘积最大f[i,j]:=max(f[k,j-1]*mult[k,i]);7.资源问题3-----系统可靠性(完全背包)F[i,j]:=max{f[i-1,j-c[i]*k]*P[I,x]}8.贪心的动态规划1-----快餐问题F[i,j,k]:=max{f[i-1,j',k']+(T[i]-(j-j')*p1-(k-k')*p2) div p3}9.贪心的动态规划2-----过河f[i]=min{{f(i-k)} (not stone[i]){f(i-k)}+1} (stone[i]); +贪心压缩状态10.剖分问题4-----多边形-讨论的动态规划F[i,j]:=max{正正 f[I,k]*f[k+1,j];负负 g[I,k]*f[k+1,j];正负 g[I,k]*f[k+1,j];负正 f[I,k]*g[k+1,j];} g为min11.树型动态规划1-----加分二叉树 (从两侧到根结点模型)F[I,j]:=max{f[I,k-1]*f[k+1,j]+c[k]}12.树型动态规划2-----选课 (多叉树转二叉树,自顶向下模型)F[I,j]表示以i为根节点选j门功课得到的最大学分f[i,j]:=max{f[t[i].l,k]+f[t[i].r,j-k-1]+c[i]}13.计数问题1-----砝码称重f[f[0]+1]=f[j]+k*w[j];(1<=i<=n; 1<=j<=f[0]; 1<=k<=a[i];)14.递推天地1------核电站问题f[-1]:=1; f[0]:=1;f[i]:=2*f[i-1]-f[i-1-m]15.递推天地2------数的划分f[i,j]:=f[i-j,j]+f[i-1,j-1];16.最大子矩阵1-----一最大01子矩阵f[i,j]:=min(f[i-1,j],v[i,j-1],v[i-1,j-1])+1;ans:=maxvalue(f);17.判定性问题1-----能否被4整除g[1,0]:=true; g[1,1]:=false; g[1,2]:=false; g[1,3]:=false; g[i,j]:=g[i-1,k] and ((k+a[i,p]) mod 4 = j)18.判定性问题2-----能否被k整除f[I,j±n[i] mod k]:=f[i-1,j]; -k<=j<=k; 1<=i<=n20.线型动态规划2-----方块消除游戏f[i,i-1,0]:=0f[i,j,k]:=max{f[i,j-1,0]+sqr(len(j)+k),f[i,p,k+len[j]]+f[p+1,j-1,0]}ans:=f[1,m,0]21.线型动态规划3-----最长公共子串,LCS问题f[i,j]={0(i=0)&(j=0);f[i-1,j-1]+1(i>0,j>0,x[i]=y[j]);max{f[i,j-1]+f[i-1,j]}} (i>0,j>0,x[i]<>y[j]);22.最大子矩阵2-----最大带权01子矩阵O(n^2*m)枚举行的起始,压缩进数列,求最大字段和,遇0则清零23. 资源问题4-----装箱问题(判定性01背包)f[j]:=(f[j] or f[j-v[i]]);24.数字三角形1-----朴素の数字三角形f[i,j]:=max(f[i+1,j]+a[I,j],f[i+1,j+1]+a[i,j]);25.数字三角形2-----晴天小猪历险记之Hill同一阶段上暴力动态规划if[i,j]:=min(f[i,j-1],f[I,j+1],f[i-1,j],f[i-1,j-1])+a[i,j]26.双向动态规划1数字三角形3-----小胖办证f[i,j]:=max(f[i-1,j]+a[i,j],f[i,j-1]+a[i,j],f[i,j+1]+a[i,j])27. 数字三角形4-----过河卒//边界初始化f[i,j]:=f[i-1,j]+f[i,j-1];28.数字三角形5-----朴素的打砖块f[i,j,k]:=max(f[i-1,j-k,p]+sum[i,k],f[i,j,k]);29.数字三角形6-----优化的打砖块f[I,j,k]:=max{g[i-1,j-k,k-1]+sum[I,k]}30.线性动态规划3-----打鼹鼠’f[i]:=f[j]+1;(abs(x[i]-x[j])+abs(y[i]-y[j])<=t[i]-t[j])31.树形动态规划3-----贪吃的九头龙⎭⎬⎫⎩⎨⎧======⎭⎬⎫⎩⎨⎧+-++--+=0))2()0(&)0(())1(&)1((1],[]][,[*]0,[],',[]0,',[]][,[*]1,[],1',[]1,',[min ],,[m and j i or j i j i d i p i w k d k j j r f j l f i p i w k d k j j r f j l f k j i f32.状态压缩动态规划1-----炮兵阵地Max(f[Q*(r+1)+k],g[j]+num[k])If (map[i] and plan[k]=0) and((plan[P] or plan[q]) and plan[k]=0)33.递推天地3-----情书抄写员f[i]:=f[i-1]+k*f[i-2]34.递推天地4-----错位排列f[i]:=(i-1)(f[i-2]+f[i-1]);f[n]:=n*f[n-1]+(-1)^(n-2);35.递推天地5-----直线分平面最大区域数f[n]:=f[n-1]+n:=n*(n+1) div 2 + 1;36.递推天地6-----折线分平面最大区域数f[n]:=(n-1)(2*n-1)+2*n;37.递推天地7-----封闭曲线分平面最大区域数f[n]:=f[n-1]+2*(n-1):=sqr(n)-n+2;38递推天地8-----凸多边形分三角形方法数f[n]:=C(2*n-2,n-1) div n;对于k 边形f[k]:=C(2*k-4,k-2) div (k-1); //(k>=3)39递推天地9-----Catalan 数列一般形式1,1,2,5,14,42,132f[n]:=C(2k,k) div (k+1);40递推天地10-----彩灯布置排列组合中的环形染色问题f[n]:=f[n-1]*(m-2)+f[n-2]*(m-1); (f[1]:=m; f[2]:=m(m-1);41线性动态规划4-----找数线性扫描sum:=f[i]+g[j];(if sum=Aim then getout; if sum<Aim then inc(i) else inc(j);)42线性动态规划5-----隐形的翅膀min:=min{abs(w[i]/w[j]-gold)};if w[i]/w[j]<gold then inc(i) else inc(j);43剖分问题5-----最大奖励f[i]:=max(f[i],f[j]+(sum[j]-sum[i])*i-t44最短路1-----Floydf[i,j]:=max(f[i,j],f[i,k]+f[k,j]);ans[q[i,j,k]]:=ans[q[i,j,k]]+s[i,q[i,j,k]]*s[q[i,j,k],j]/s[i,j];45 剖分问题6-----小H 的小屋F[l,m,n]:=f[l-x,m-1,n-k]+S(x,k);46 计数问题2-----陨石的秘密(排列组合中的计数问题)Ans[l1,l2,l3,D]:=f[l1+1,l2,l3,D+1]-f[l1+1,l2,l3,D];F[l1,l2,l3,D]:=Sigma(f[o,p,q,d-1]*f[l1-o,l2-p,l3-q,d]);47 线性动态规划------合唱队形两次F[i]:=max{f[j]+1}+枚举中央结点48 资源问题------明明的预算方案:加花的动态规划f[i,j]:=max(f[i,j],f[l,j-v[i]-v[fb[i]]-v[fa[i]]]+v[i]*p[i]+v[fb[i]]*p[fb[i]]+v[fa[i]]*p[fa[i]]);49 资源问题-----化工场装箱员[,[1,],[1,]][,,]:min [,[1,],[1,]]1[10,[1,10],[1,10]f n i getA n n i j getB n n i f n i j f n j i getA n n j getB n n j f n i j i getA n n i j j getB n n i j ++++++⎧⎫⎪⎪=+++++++⎨⎬⎪⎪+--+++--+++--⎩⎭-----聚会的快乐f[i,2]:=max(f[i,0],f[i,1]);f[i,1]:=sigma(f[t[i]^.son,0]);f[i,0]:=sigma(f[t[i]^.son,3]);51树形动态规划-----皇宫看守f[i,2]:=max(f[i,0],f[i,1]);f[i,1]:=sigma(f[t[i]^.son,0]);f[i,0]:=sigma(f[t[i]^.son,3]);52递推天地-----盒子与球f[i,1]:=1;f[i,j]:=j*(f[i-1,j-1]+f[i-1,j]);53双重动态规划-----有限的基因序列f[i]:=min{f[j]+1}g[c,i,j]:=(g[a,i,j] and g[b,i,j]) or (g[c,i,j])54最大子矩阵问题-----居住空间f[i,j,k]:=min(min(min(f[i-1,j,k],f[i,j-1,k]),min(f[i,j,k-1],f[i-1,j-1,k])),min(min(f[i-1,j,k-1],f[i,j-1,k-1]),f[i-1,j-1,k-1]))+1;55线性动态规划------日程安排f[i]:=max{f[j]}+P[I]; (e[j]<s[i])56递推天地------组合数C[I,j]:=C[i-1,j]+C[I-1,j-1]C[I,0]:=157树形动态规划-----有向树k中值问题F[I,r,k]:=max{max{f[l[i],I,j]+f[r[i],I,k-j-1]},f[f[l[i],r,j]+f[r[i],r,k-j]+w[I,r]]}58树形动态规划-----CTSC 2001选课F[I,j]:=w[i](if i∈P)+f[l[i],k]+f[r[i],m-k](0≤k≤m)(if l[i]<>0)-----多重历史f[i,j]:=sigma{f[i-k,j-1]}(if checked)60背包问题(+-1背包问题+回溯)-----CEOI1998 Substractf[i,j]:=f[i-1,j-a[i]] or f[i-1,j+a[i]]61线性动态规划(字符串)-----NOI 2000 古城之谜f[i,1,1]:=min{f[i+length(s),2,1],f[i+length(s),1,1]+1}f[i,1,2]:=min{f[i+length(s),1,2]+words[s],f[i+length(s),1,2]+words[s]}62线性动态规划-----最少单词个数f[i,j]:=max{f[I,j],f[u-1,j-1]+l}63线型动态规划-----APIO2007 数据备份状态压缩+剪掉每个阶段j前j*2个状态和j*2+200后的状态贪心动态规划f[i]:=min(g[i-2]+s[i],f[i-1]);64树形动态规划-----APIO2007 风铃f[i]:=f[l]+f[r]+{1 (if c[l]<c[r])}g[i]:=1(d[l]<>d[r]) 0(d[l]=d[r])g[l]=g[r]=1 then Halt;65地图动态规划-----NOI 2005 adv19910F[t,i,j]:=max{f[t-1,i-dx[d[[t]],j-dy[d[k]]]+1],f[t-1,i,j];66地图动态规划-----优化的NOI 2005 adv19910F[k,i,j]:=max{f[k-1,i,p]+1} j-b[k]<=p<=j;67目标动态规划-----CEOI98 subtraF[I,j]:=f[I-1,j+a[i]] or f[i-1,j-a[i]]68目标动态规划----- Vijos 1037搭建双塔问题F[value,delta]:=g[value+a[i],delta+a[i]] or g[value,delta-a[i]]69树形动态规划-----有线电视网f[i,p]:=max(f[i,p],f[i,p-q]+f[j,q]-map[i,j])leaves[i]>=p>=l, 1<=q<=p;70地图动态规划-----vijos某题F[I,j]:=min(f[i-1,j-1],f[I,j-1],f[i-1,j]);71最大子矩阵问题-----最大字段和问题f[i]:=max(f[i-1]+b[i],b[i]); f[1]:=b[1]72最大子矩阵问题-----最大子立方体问题枚举一组边i的起始,压缩进矩阵 B[I,j]+=a[x,I,j]枚举另外一组边的其实,做最大子矩阵73括号序列-----线型动态规划f[I,j]:=min(f[I,j],f[i+1,j-1](s[i]s[j]=”()”or(”[]”)),f[I+1,j+1]+1 (s[j]=”(”or”[” ] , f[I,j-1]+1(s[j]=”)”or”]” )74棋盘切割-----线型动态规划f[k,x1,y1,x2,y2]=min{min{f[k-1,x1,y1,a,y2]+s[a+1,y1,x2,y2],f[k-1,a+1,y1,x2,y2]+s[x1,y1,a,y2]min{}}75概率动态规划-----聪聪和可可(NOI2005)x:=p[p[i,j],j]f[I,j]:=(f[x,b[j,k]]+f[x,j])/(l[j]+1)+1f[I,i]=0f[x,j]=176概率动态规划-----血缘关系F[A, B]=(f[A0, B]+P[A1, B])/2f[I,i]=1f[I,j]=0(I,j无相同基因)77线性动态规划-----决斗F[I,j]=(f[I,j] and f[k,j]) and (e[I,k] or e[j,k]),i<k<j78线性动态规划-----舞蹈家F[x,y,k]=min(f[a[k],y,k+1]+w[x,a[k]],f[x,a[k],k+1]+w[y,a[k]])79线性动态规划-----积木游戏F[I,a,b,k]=max(f[I,a+1,b,k],f[i+1,a+1,a+1,k’],f[I,a+1,a+1,k’])80树形动态规划(双次记录)-----NOI2003 逃学的小孩朴素的话枚举节点i和离其最远的两个节点 j,k O(n^2)每个节点记录最大的两个值,并记录这最大值分别是从哪个相邻节点传过来的。
转载-夜深人静写算法(二)-动态规划

转载-夜深⼈静写算法(⼆)-动态规划【例题7】给定⼀个长度为n(n <= 1000)的字符串A,求插⼊最少多少个字符使得它变成⼀个回⽂串。
典型的区间模型,回⽂串拥有很明显的⼦结构特征,即当字符串X是⼀个回⽂串时,在X两边各添加⼀个字符'a'后,aXa仍然是⼀个回⽂串,我们⽤d[i][j]来表⽰A[i...j]这个⼦串变成回⽂串所需要添加的最少的字符数,那么对于A[i] == A[j]的情况,很明显有 d[i][j] = d[i+1][j-1] (这⾥需要明确⼀点,当i+1 > j-1时也是有意义的,它代表的是空串,空串也是⼀个回⽂串,所以这种情况下d[i+1][j-1] = 0);当A[i] != A[j]时,我们将它变成更⼩的⼦问题求解,我们有两种决策:1、在A[j]后⾯添加⼀个字符A[i];2、在A[i]前⾯添加⼀个字符A[j];根据两种决策列出状态转移⽅程为:d[i][j] = min{ d[i+1][j], d[i][j-1] } + 1; (每次状态转移,区间长度增加1)空间复杂度O(n^2),时间复杂度O(n^2),下⽂会提到将空间复杂度降为O(n)的优化算法。
3、背包模型背包问题是动态规划中⼀个最典型的问题之⼀。
由于⽹上有⾮常详尽的背包讲解,这⾥只将常⽤部分抽出来,具体推导过程详见。
a.0/1背包有N种物品(每种物品1件)和⼀个容量为V的背包。
放⼊第 i 种物品耗费的空间是Ci,得到的价值是Wi。
求解将哪些物品装⼊背包可使价值总和最⼤。
f[i][v]表⽰前i种物品恰好放⼊⼀个容量为v的背包可以获得的最⼤价值。
决策为第i个物品在前i-1个物品放置完毕后,是选择放还是不放,状态转移⽅程为:f[i][v] = max{ f[i-1][v], f[i-1][v - Ci] +Wi }时间复杂度O(VN),空间复杂度O(VN) (空间复杂度可利⽤滚动数组进⾏优化达到O(V),下⽂会介绍滚动数组优化)。
动态规划的状态转移方程

动态规划的状态转移方程动态规划是一种常用的求解最优化问题的方法,广泛应用于计算机科学、数学和经济学等领域。
在动态规划中,状态转移方程是关键步骤,它描述了问题的状态如何从一个状态转移到下一个状态。
本文将详细介绍动态规划的状态转移方程及其应用。
一、动态规划的基本原理动态规划是一种将复杂问题分解成更小且重叠的子问题来求解的方法。
它的基本思想是利用已经计算过的子问题的解来求解当前问题的解,从而避免重复计算,提高计算效率。
二、状态转移方程的定义状态转移方程是动态规划中的重要概念,它描述了问题的状态如何从一个阶段转移到下一个阶段。
状态转移方程通常使用递推的方式来表示,即通过已知状态推导出未知状态。
在解决最优化问题时,我们通常需要定义一个目标函数,通过优化目标函数来求解最优解。
状态转移方程可以将目标函数从一个阶段递推到另一个阶段,从而求解出最优解。
三、状态转移方程的形式状态转移方程的形式可以根据具体问题的特点灵活定义。
一般来说,状态转移方程包括以下几个要素:1. 状态的定义:将问题划分为若干个阶段,并定义每个阶段的状态。
状态可以是一个变量、一个数组或其他数据结构。
2. 状态转移的定义:描述问题的状态如何从一个阶段转移到下一个阶段。
状态转移可以使用数学表达式、递归方程或其他形式表示。
3. 初始状态和边界条件:确定问题的起始状态和终止状态,并定义边界条件。
四、举例说明以经典的背包问题为例,我们来看一下如何使用状态转移方程解决问题。
背包问题是一个经典的组合优化问题,给定一个背包的容量和一组物品,每个物品有一个重量和一个价值,需要选择一些物品放入背包中,使得背包的总重量不超过容量,且总价值最大。
在解决背包问题时,我们可以将其划分为若干个阶段,每个阶段表示选择第i个物品放入背包的决策。
我们可以定义一个二维数组dp[i][j]来表示在前i个物品中,背包容量为j时的最大价值。
状态转移方程可以表示为:dp[i][j] = max(dp[i-1][j], dp[i-1][j-w[i]] + v[i])其中,dp[i-1][j]表示不选择第i个物品时的最大价值,dp[i-1][j-w[i]] + v[i]表示选择第i个物品时的最大价值。
最短路径问题的动态规划算法

最短路径问题的动态规划算法最短路径问题的动态规划算法是一种常用的解决路径优化的方法。
动态规划算法的核心思想是将原问题拆分成若干个子问题,通过递推关系找到最优解。
在最短路径问题中,我们通常希望找到从起点到终点的最短路径。
首先,我们需要定义一个二维数组dp,其中dp[i][j]表示从起点到达坐标(i, j)的最短路径长度。
初始化dp数组,将起点的值设为0,其他位置的值设为无穷大(即表示不可达)。
接下来,我们需要确定动态规划的状态转移方程。
对于任意一个坐标(i, j),它可以从上方的坐标(i-1, j)、左方的坐标(i, j-1)、右方的坐标(i, j+1)、下方的坐标(i+1, j)四个位置中的某一个到达。
因此,可以得到状态转移方程如下:
dp[i][j] = min(dp[i-1][j], dp[i][j-1], dp[i][j+1], dp[i+1][j]) + 1
其中,min表示取其中的最小值。
通过以上状态转移方程,我们可以逐步更新dp数组,直到最终得到终点的最短路径长度。
需要注意的是,动态规划算法的时间复杂度通常是O(n^2),其中n 表示问题规模。
因此,在处理大规模最短路径问题时,需要考虑算法的效率,可能需要进行剪枝等优化操作。
总的来说,最短路径问题的动态规划算法在路径优化领域有着重要的应用价值,通过合理定义状态转移方程和优化算法效率,可以找到从起点到终点的最短路径长度,为路径规划提供有效的解决方案。
4种常见的动态规划模型

例谈四种常见的动态规划模型动态规划是解决多阶段决策最优化问题的一种思想方法,本文主要结合一些例题,把一些常见的动态规划模型,进行归纳总结。
(一)、背包模型可用动态规划解决的背包问题,主要有01背包和完全背包。
对于背包的类型,这边就做个简单的描述:n个物品要放到一个背包里,背包有个总容量m,每个物品都有一个体积w[i]和价值v[i],问如何装这些物品,使得背包里放的物品价值最大。
这类型的题目,状态表示为:f[j]表示背包容量不超过j时能够装的最大价值,则状态转移方程为:f[j]:=max{f[j-w[i]]+v[i]},边界:f[0]:=0;简单的程序框架为:beginreadln(m,n);for i:=1 to n do readln(w[i],v[i]);f[0]:=0;for i:=1 to m dofor j:=1 to n dobeginif i>=w[j] then t:=f[i-w[j]]+v[j];if t>f[i] then f[i]:=t;end;writeln(f[m]);end.这类型的题目应用挺广的(noip1996提高组第4题,noip2001普及组装箱问题,noip2005普及组采药等),下面一个例子,也是背包模型的简单转化。
货币系统(money)【问题描述】母牛们不但创建了他们自己的政府而且选择了建立了自己的货币系统。
他们对货币的数值感到好奇。
传统地,一个货币系统是由1,5,10,20或25,50,100的单位面值组成的。
母牛想知道用货币系统中的货币来构造一个确定的面值,有多少种不同的方法。
使用一个货币系统{1,2,5,10,..}产生18单位面值的一些可能的方法是:18×1,9×2,8×2+2×1,3×5+2+1等等其它。
写一个程序来计算有多少种方法用给定的货币系统来构造一个确定的面值。
【输入格式】货币系统中货币的种类数目是v(1≤v≤25);要构造的面值是n(1≤n≤10,000);第1行:二个整数,v和n;第2..v+1行:可用的货币v个整数(每行一个)。
状态转移方程

状态转移方程
各位读友大家好,此文档由网络收集而来,欢迎您下载,谢谢
状态转移方程。状态转移方程。是动态规划中本阶段的状态往往是上一阶段状态和上一阶段决策的结果。
如果给定了第K阶段的状态Sk以及决策uk。则第K+1阶段的状态Sk+1也就完全确定。
中文名,状态转移方程。应用学科,编程。适用领域范围,DP问题。适用领域范围,动态规划算法。
设计适用条件
任何思想方法都有一定的局限性,超出了特定条件,它就失去了作用。同样,动态规划也并不是万能的。适用动态规划的问题必须满足最优化原理和无后效性。
1.最优化原理最优化原理可这样阐述:一个最优化策略具有这样的性质,不论过去状态和决策如何,对前面的决策所形成的状态而言,余下的诸决策必须构成最优策略。简而言之,一个最优化策略的子策略总是最优的。一个问题满足最优化原理又称其具有最优子结构性质。
2.无后效性将各阶段按照一定的次序排列好之后,对于某个给定的阶段状态,它以前各阶段的状态无法直接影响它未来的决策,而只能通过当前的这个状态。换句话说,每个状态都是过去历史的一个完整总结。这就是无后向性,又称为无后效性。
3.子问题的重叠性动态规划将原来具有指数级时间复杂度的搜索算法改进成了具有多项式时间复杂度的算法。其中的关键在于解决冗余,这是动态规划算法的根本目的。动态规划实质上是一种以空间换时间的技术,它在实现的过程中,不得不存储产生过程中的各种状态,所以它的空间复杂度要大于其它的算法。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
for j:=v[i] to w do
begin
if f[i-1,j-v[i]]+a[i]>f[I,j] then f[I,j]:= f[i-1,j-v[i]]+a[i]>f[I,j] end; End;
完善程序
1、初始化? Fillchar(f,sizeof(F),0) 2、最终解在哪里? F[n,w]中。因为每个阶段的f[I,j]表示的是
核心程序段
fillchar(f,sizeof(f),0); for i:=1 to n do for j:=1 to v do begin f[i,j]:=f[i-1,j]; if (v1[i]<=j) and (f[i,j]<f[i-1,j-v1[i]]+p[i]) then f[i,j]:=f[i-1,j-v1[i]]+p[i]; end; write(f[n,v]);
彩石运输
阿强是一个汽车运输工,他正在给一项装饰工程运输所需
的彩色石头。这些石头的颜色各异,价格也各不相同。有 一天阿强突发奇想,他想在一堆彩石中有选择地把彩石装 上他的卡车,使得卡车上装载的石头总价值是所有装载方 案中最大的。现在有一堆彩石堆放在阿强面前,他知道任 何两块石头的颜色都是不同的,但两块颜色不同的石头的 重量和价格可能相同。 阿强的卡车总共可装载的重量是W,而且他知道总的彩 石的块数,请你帮助阿强确定一个方案,满足阿强的奇想。 输入文件stone.in的第一行是二个整数,依次表示卡车 的载重量W和总的彩石块数n,下面共有n行,每行包含二 个用空格分隔的整数,依次表示某种颜色彩石的重量和价 值。 输出文件stone.out只包含一行一个整数,表示卡车最终 装载彩石的最大总价值。
输入和输出
joy.in 23 5 11 20 9 19 10 15 7 14 8 15 joy.out 39
关键要素分析
1、阶段 2、状态 3、决策
分析状态转移方程
F[I,j]表示前i个工具选择部分装入占用容量
为j的工具箱中的最大效率分:
f[i,j]:=max{f[i-1,j-v1[i]]+p[i] |}
begin
f[I,j]:=f[i-1,j]; if (w[i]<=w) and (f[I,j]<f[i-1,j-w[i]]+p[i]) then
f[I,j]:=f[i-1,j-w[i]]+p[i]; end; write(f[n,w]);
joy的工具箱
Joy是一位非常出色的汽车维修工,而且他的创业能力也很强,这不,
满背包,那么问题就是“背包单位体积所 含价值最大” 2、可能出现的情况是某些性价比较高的 物品装入后导致其他性价比较低物品不能 装入,导致背包体积被浪费。所以不能再 用贪心了 3、只能用DP解决
01背包问题
枚举阶段(所有物品)
For i:=1 to n do for j:=0 to w do begin f[I,j]:=f[i-1,j];
前i个物品装入j体积的背包中的最大值, 而不是第i个物品装入j中的最大值。
扩展01背包问题
N种物品,每种有无穷多个,价值为a[i],
单个体积为v[i],装入总体积为W的背包, 求最大价值和。
扩展01背包问题
穷举所有阶段I
{物品编号} 穷举状态j {当前背包被占用} 穷举决策k {k:=0 to w/v[i]} 根据决策转移状态到上个可以的子状 态,比较各个状态转移后的最优解f[I,j]; end; end; End;
扩展01背包问题
1、k=0时表示物品i不取,则对应的
f[I,j]=f[i-1,j] 2、k>0时,表示物品i装入了被占用j体积 的背包中有k个,这个决策对应的上个可 能的子状态是:背包被占用体积是j-v[i] (可以不管当前装入的物品i已经装入几个 了)。对应的最优解就是:f[I,j]:=f[I,jv[i]]+a[i]
初步的程序结构
For i:=1 to n do for j:=1 to w do begin
f[I,j]:=f[i-1,j]; {不取当前物品i} for k:=1 to j/v[i] do if (j>=k*v[i]) and (f[I,j]<=f[I,j-v[i]]+a[i]) then f[I,j]:=f[I,j-v[i]]+a[i]; end; end;
前期分析
1、什么是矩阵乘法 2、乘法次数的统计原理
算法分析
1、阶段。分相邻二个矩阵相乘、相邻三
个相乘、……n个矩阵相乘来划分阶段。
2、状态。连乘矩阵的起始和终止编号。
3、决策。在i和j矩阵之间如何组合。
状态转移方程
1、f[I,j]表示第i个矩阵到第j个矩阵连乘的
最少次数。 2、a[i].x a[i].y表示第i个矩阵的行号和列 号 3、转移方程: F[I,j]=min{F[I,k]+f[k+1,j]+ai.x*ai.y*aj.y}
枚举状态(当前背包被 占用体积) 当前物品不装入背包的最大总价值就是 前i-1个物品装入背包的最大值。
if (j>=v[i]) and (f[i-1,j-v[i]]+a[i]>f[I,j])
then f[I,j]:= f[i-1,j-v[i]]+a[i]>f[I,j] end; 把当前背包不装入和装入进行比较,哪个更大,
Tom当然希望能把所有的零件都加工完,
总体算法分析
1、先用循环求得所有的f[I,i+1],1<=i<n 2、以合并包含的原始石子堆的数量为阶
段(从3到n),进行动态规划求解。 3、输出f[1,n]。
TOM的烦恼
Tom是一个非常有创业精神的人,由于大学学的
是汽车制造专业,所以毕业后他用有限的资金开 了一家汽车零件加工厂,专门为汽车制造商制造 零件。由于资金有限,他只能先购买一台加工机 器。现在他却遇到了麻烦,多家汽车制造商需要 他加工一些不同零件(由于厂家和零件不同,所 以给的加工费也不同),而且不同厂家对于不同 零件的加工时间要求不同(有些加工时间要求甚 至是冲突的,但开始和结束时间相同不算冲突)。
最近他成立了自己的汽车维修110公司,一旦汽车在半途抛锚,只要 一个电话,joy就会立刻带着他的工具箱赶到事故地点,为驾驶员朋 友维修汽车,由于抢修及时以及维修技术高,汽车维修110公司的生 意越来越红火。 但joy是一个追求无止境的人,在生意越做越大的同时,他又动开 了新脑筋。他发现无论维修工具箱买得如何大,肯定不能把他公司 里所有的维修工具装进去,100%的故障排除率不仅需要精湛的维修 技术,如何选择并把最为合适的维修工具装入工具箱,并把工具箱 带到故障现场,也是一个非常重要的技巧。由于工具众多,joy无法 根据驾驶员报告的故障现象确定最为合适的一些工具,作为朋友的 你决定通过程序来帮助joy选择最为合适的工具转入到工具箱中。
经典问题:矩阵连乘
有n个矩阵,计算他们连乘的最少乘法次
数。 输入第一行为一个整数n,表示参加连乘 的矩阵的个数,下面n行,依次出各个 矩阵的行数和列数规模。 输出最少的乘法次数(连乘目标是只有一 个矩阵)。
输入和输出
输入: 3 1 5 5 20 20 1
输出:
105
加。
状态转移分析
1、用a[i]表示第i堆石子的数量 2、f[I,j]表示第i堆到第j堆合并为一堆的最
小分数 3、f[I,j]=min{f[I,k]+f[k+1,j]+sigma(a[t] | i<=t<=j) | i<=k<j} 4、初始化时必须是:f[I,i]:= maxint;f[I,i]:=0
另一种形式的程序
For i:=1 to n do for j:=1 to v[i]-1 do f[I,j]:=f[i-1,j]; for j:=v[i] to w do if f[i-1,j]>f[I,j-v[i]]+a[i] then
f[I,j]:=f[i-1,j] else f[I,j]:=f[I,j-v[i]]+a[i];
部分背包问题算法
为了让每份背包单位体积价值最大,只要
对所有物品按照性价比从大到小排序,依 次装入物品即可,直到背包满或者没有物 品可取
01背包问题
N个物品每个有价值a[i]和体积v[i],但每
个物品不能分割(要么全部取,要么不 取),求最大的背包所含的价值。
01背包问题
1、如果不管哪个物品装入,都能恰好装
首先是两两相乘
For i:=1 to n-1 do
F[i,i+1]:=a[i].x*a[i].y*a[i+1].y;
然后是更大规模的连乘
For len:=3 to n do
For i:=1 to n-len+1 do Begin j:=i+len-1;F[i,j]:=maxlongint; For k:=i to j-1 do If F[i,j]>F[i,k]+F[k+1,j]+a[i].x*a[k].y*a[j].y Then Begin F[i,j]:=F[i,k]+F[k+1,j]+a[i].x*a[k].y*a[j].y; End; End ;
难度是子状态的转移,上一个子状态就是j-v[i], 因为v[i]装入前,背包被占用体积就是j-v[i]。
可以和tom问题中的状态转移联系起来,当前任务完成 的前一个子状态就是当前时刻减去当前任务占用时间