4种常见的动态规划模型
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
例谈四种常见的动态规划模型
动态规划是解决多阶段决策最优化问题的一种思想方法,本文主要结合一些例题,把一些常见的动态规划模型,进行归纳总结。
(一)、背包模型
可用动态规划解决的背包问题,主要有01背包和完全背包。
对于背包的类型,这边就做个简单的描述:n个物品要放到一个背包里,背包有个总容量m,每个物品都有一个体积w[i]和价值v[i],问如何装这些物品,使得背包里放的物品价值最大。这类型的题目,状态表示为:f[j]表示背包容量不超过j时能够装的最大价值,则状态转移方程为:f[j]:=max{f[j-w[i]]+v[i]},边界:f[0]:=0;
简单的程序框架为:
begin
readln(m,n);
for i:=1 to n do readln(w[i],v[i]);
f[0]:=0;
for i:=1 to m do
for j:=1 to n do
begin
if 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个整数(每行一个)。
【输出格式】
单独的一行包含那个可能的构造的方案数。
【输入样例】
3 10
1
2
5
【输出样例】
10
[分析]:此题是个背包模型,只是问题的解是构造方案数,设w[j]为第j种币值,状态f[i]:构造面值为i时可能的方案数,则状态转移方程为:f[i]:=∑f[i-w[j]],i>=w[j],边界:f[0]:=1;f[n]即为问题的解。
注意:由于此题的数据规模比较大,所以要用到高精度加法,估计最大的数据可以达到73位,为节约程序时间和空间效率,还采用了万进制的高精度加法。参考程序
如下:
var
f:array[0..10000,1..20]of integer;
long:array[0..10000]of integer;25]of integer;
n,m,i,j,k:integer;
procedure add(r,t:integer);(二)、资源分配模型
资源分配模型的动态规划,这类型的题目一般是:给定m个资源,分配给n个部门,第i个部门获得j个资源有个盈利值,问如何分配这m个资源能使获得的盈利最大,求最大盈利。这类型的题目一般用资源数做状态,数组f[i,j]表示前个i个部门分配j个资源的最大盈利,则状态转移方程为:f[i,j]:=max{f[i-1,k]+value[i,j-k]} (0<=k<=j) 程序框架如下:
var i,j,k:longint;
begin
for i:=1 to n do
for j:=0 to m do
for k:=0 to j do
if f[i-1,k]+value[i,j-k]>f[i,j] then f[i,j]:=f[i-1,k]+value[i,j-k];
writeln(f[n,m]);
end;
资源分配类型典型应用是花店橱窗设置,没做过的同学可以自己去练习一下,下面的一个例题,也是此类型的转换。
[问题描述]
农夫ion放完马以后,需要把马儿关回马厩。为了做好这件事,ion让马排成一行跟着他入马厩。他想出了一个就近入厩的办法:让前p1匹马进入第一个马厩,然后的p2匹马进入第二个马厩,如此类推。而且,他不想让任何一个马厩(共k个)留空,还有所有的马都进入马厩。
已知ion只有黑色和白色两种颜色的马,然而并不是所有的马都能相处融洽。假如有i 匹黑马和j匹白马同在一个马厩,那么它们之间的不愉快系数为i*j。马厩总的不愉快系数等于k个马厩的不愉快系数之和。
请帮忙把n匹马按顺序放入k个马厩中(即求一种 p1,p2…的安排方案),使得总的不愉快系数最小。
[输入格式]
输入第一行为一个n和k;(n<=100,k<=n);
输入第二行为n个数0和1,0表示白马,1表示黑马
[输出格式]
一行,最小的不愉快系数。
样例输入
3 2
1 0 1
样例输出
1
分析:设f[i,j]:表示将前i匹马放入前j个马厩,得到的最小不愉快系数。w[i,j]:表示将第i至第j匹马放入同一个马厩所得到的不愉快系数。
状态转移方程为:f[i,j]=min(f[k,j-1]+w[k+1,i]){j-1<=k
注意边界条件:f[i,1]:=w[1,i];f[i,i]:=0;
参考程序如下:
const maxn=100;maxk=100;
var
f:array[1..maxn,1..maxk]of longint;
w:array[1..maxn,1..maxn]of longint;
a:array[1..maxn]of longint;
i,j,k,k1,n,s1,s2:integer;
begin
assign(input,''); reset(input);
assign(output,’’); rewrite(output);
readln(n,k);
for i:=1 to n do read(a[i]);
for i:=1 to n do (三)、区间类模型
区间类模型的动态规划,一般是要求整段区间的最优值,子问题一般是把区间分成两个子区间。一般用二维数组表示状态,例如f[i,j]表示从i到j的最优值。则状态转移方程就是跟子区间之间的关系,下面我们用个典型的例子讲解这个模型的应用。
[问题描述]
给定一个具有n(n<50)个顶点(从1到n编号)的凸多边形,每个顶点的权均已知。问如何把这个凸多边形划分成n-2个互不相交的三角形,使得这些三角形顶点的权的乘积之和最小?
输入文件:
第一行顶点数n
第一行n个顶点(从1到n)的权值
输出格式:
最小的和的值,各三角形组成的方式
输入示例:
5
122 123 245 231
输出示例:
t he minimum is :
the formation of 3 triangle:3 4 5,1 5 3,1 2 3
分析:这是一道很典型的区间模型动态规划问题。设f[i,j](i