1 / 19
文档名称:

动态规划1.ppt

格式:ppt   大小:102KB   页数:19页
下载后只包含 1 个 PPT 格式的文档,没有任何的图纸或源代码,查看文件列表

如果您已付费下载过本站文档,您可以点这里二次下载

分享

预览

动态规划1.ppt

上传人:iris028 2022/7/13 文件大小:102 KB

下载得到文件列表

动态规划1.ppt

相关文档

文档介绍

文档介绍:石子归并问题:
N堆石子摆放成一列(N<=100),现要将石子有次序地合并成一堆。规定每次只能选相邻的两堆合并成一堆,并将新的一堆的石子数记为该次合并的得分。
(1)选择一种合并石子的方案,使得做N-1次合并,得分的总和:
以递归函数实现,效率低甚至堆栈溢出;
非递归方式:
以三维数组f来记录函数的值,则需200*200*(200*40)个存储空间。
观察f(i,j,k)仅由f(i-1,x,y)部分即可求得,与f(m,x,y)无关(0<m<i-1).因此可以用两个二维数组来表示相邻的f(i,j,k)和f(i+1,j,k),令
f[j][k]表示从前i个数中选取j个能否得到和k;
f1[j][k]表示从前i+1个数中选取j个能否得到和k;
那么:
f1[j][k]=f[j][k] or f[j-1][k-ai+1].
迭代即可求得f(n,(n+1) div 2,k).
for i:=1 to n do sum[i]:=sum[i-1]+a[i];
f[1][a[1]]:=true;
for i:=2 to n do
begin
f1[1][a[i]]:=true; m:=(n+1) div 2; if i<m then m:=i;
for j:=2 to m do
for k:=0 to sum[i] do
begin
f1[j][k]:=f[j][k];
if k-a[i]>=0 then f1[j][k]:=f1[j][k] or f[j-1][k-a[i]];
end;
for j:=1 to m do
for k:=0 to sum[i] do f[j][k]:=f1[j][k];
end;
进一步的优化:
考虑较特殊的数据,例如:
n=200,a1=1,a2=a3=···=an=40.
把成对出现的多个最大值平分到两个部分可以提高效率.
当然,某些数据可能不适用,例如:
n=9
a1=a2=a3=a4=a5=32
A6=a7=a8=a9=40
集合:
搜索可以求解,但效率较低,剪枝优化效果不够明显。
经分析,该题目是要求把1···n分成两个集合,使每个集合中元素之和为n*(n+1) div 4的方案.
首先当n mod 4=1或2时方案数为0;
对于n mod 4=0或3的情况:
s=n*(n+1) div 4,问题转化为从1···n中取数,得到和为s的取数方法有多少种。为避免重复,设1一定不被取到,f(i,j)表示从i···n中取数得到和为j的方案数,则:f(i,j)=f(i+1,j)+f(i+1,j-i)
(2<=I<=n,0<=j<=s;f(n,0)=1; f(n,n)=1;其他函数值为0.) f(2,s)即为题目的解。
fillchar(f,sizeof(f),0); f[n][0]:=1; f[n][n]:=1;
for i:=n-1 downto 2 do
for j:=0 to n*(n+1) div 4 do
begin
f[i][j]:=f[i+1][j];
if j-i>=0 then f[i][j]:=f[i][j]+f[i+1][j-i];
end;
writeln(f[2][n*(n+1) div 4]);
滑雪:
设f(i,j)表示以点(i,j)为终点的最大长度,那么:
f(i,j)=max{f1··4(I,J)+1 }
当h(I,J)<h(i,j)且f(i,j)<=f1··4(I,J)
初始值?
高度最小的点对应的最大高度一定为1!
把所有点的高度降序排列,按顺序逐个计算相应的最大高度,则当求f(i,j)时,它周围的四个位置的最大长度已经求得。
const
d:array[1..4,1..2]of integer=
((-1,0),(0,1),(1,0),(0,-1));
var
m:array[1..500,1..500]of longint;{高度}
q:array[1..250000,1..2]of integer;{点的坐标}
f:array[1..500,1..500]of longint;
{f[i][j]:以点(i,j)为终点的最大长度}
x,y:integer;
r,c,i,j,n,t,min,max:longint;
begin
readln(r,c); n:=0;
for i:=1 to r do
begin
for j:=1 to c-1 do
begin
read(m[i][j]); n:=n+1