动态规划解析 浅谈记忆化搜索Word文档下载推荐.docx
- 文档编号:17233231
- 上传时间:2022-11-29
- 格式:DOCX
- 页数:28
- 大小:34.26KB
动态规划解析 浅谈记忆化搜索Word文档下载推荐.docx
《动态规划解析 浅谈记忆化搜索Word文档下载推荐.docx》由会员分享,可在线阅读,更多相关《动态规划解析 浅谈记忆化搜索Word文档下载推荐.docx(28页珍藏版)》请在冰豆网上搜索。
if(l[j]>
k)and(d[i]>
=d[j])thenk:
=l[j];
l[i]:
=k+1;
=1totdo
ifl[i]>
o1theno1:
=l[i];
proceduremain2;
=0totdol[i]:
=maxint;
=1totdobegin
=1too2do
=d[i])and(l[j]<
=l[k])thenk:
=j;
ifk=0thenbegin
=o2+1;
=o2;
l[k]:
=d[i];
begin
input;
main1;
main2;
output;
end.
第二题 石子合并
设f[i,j](i<
=j)表示将第i堆到第j堆石子合并为一堆所得的最大分数(最小时类似)。
问题所求即为f[1,n]。
根据合并规则,f[i,j]的解只于f[i,k],f[k+1,j](i<
j)的解有关,即问题的最优解包含了子问题的最优解,具备最优子结构。
转移方程为f[i,j]=
{f[i,k]+f[k+1,j]}+
d[p];
初始时f[k,k]=0(1<
=n);
Programgether_stone;
type
Trock_best=Array[1..100,1..100]oflongint;
Trock_k=Array[1..100,1..100]ofbyte;
Tstone=Array[0..100]ofword;
Tbak=Array[1..100]ofboolean;
var
rock_best:
^Trock_best;
rock_k:
Trock_k;
stone,tot:
Tstone;
stone1:
bak:
Tbak;
n:
Word;
functioncount(first,k,last:
Word):
longint;
s1:
iffirst<
=last
thens1:
=tot[last]-tot[first-1]
elses1:
=tot[n]+tot[last]-tot[first-1];
count:
=rock_best^[first,k]+rock_best^[(kmodn)+1,last]+s1;
functiontry(now,old:
job:
byte):
boolean;
if((job=1)and(now<
old))or((job=2)and(now>
old))
thentry:
=true
elsetry:
=false;
procedureget(first,last,job:
integer);
now:
=first;
whilek<
>
lastdo
=count(first,k,last);
iftry(now,rock_best^[first,last],job)
then
rock_best^[first,last]:
=now;
rock_k[first,last]:
=k;
=(kmodn)+1;
procedureinit;
assign(input,'
input.txt'
reset(input);
readln(n);
=1tondo
read(stone[i]);
close(input);
tot[0]:
tot[i]:
=tot[i-1]+stone[i];
new(rock_best);
assign(output,'
output.txt'
rewrite(output);
procedureinto(job:
byte);
ifjob=1
thenfillchar(rock_best^,sizeof(rock_best^),$1)
elsefillchar(rock_best^,sizeof(rock_best^),0);
fillchar(rock_k,sizeof(rock_k),0);
=1tondorock_best^[i,i]:
=stone[i];
procedureout(first,last:
i,s:
ifnot(((firstmodn)+1=last)or(first=last))
out(first,rock_k[first,last]);
out((rock_k[first,last]modn)+1,last);
iffirst=lastthenexit;
ifbak[i]=truethen
if(i=first)or(i=(rock_k[first,last]modn)+1)
thenwrite('
-'
write(stone1[i],'
'
writeln;
bak[(rock_k[first,last]modn)+1]:
iflast>
=first
thens:
elses:
=tot[last]+tot[n]-tot[first-1];
whilei<
stone1[i]:
=s;
=(imodn)+1;
stone1[last]:
procedurework(job:
i,j,k,first,last:
into(job);
=2tondo
=((i+j-2)modn)+1;
get(i,j,job);
=stone;
fillchar(bak,sizeof(bak),true);
first:
last:
=n;
if((rock_best^[i,i-1]<
rock_best^[first,last])and(job=1))or
((rock_best^[i,i-1]>
rock_best^[first,last])and(job=2))
=i-1;
out(first,last);
writeln(tot[n]);
init;
work
(1);
work
(2);
close(output);
第三题 乘积最大
问题给出了一个数字串s,求向其中加k个乘号后的最大乘积。
设f[i,j]表示向串s[1..i]中加j个乘号后的最大乘积,n=length(s)。
问题所求即为f[n,k]。
假设最优解中第k个乘号放在第i个字符后,则前k-1个乘号的放置必为子问题“向串s[1..i]中加k-1个乘号”的最优解,所以该问题具备最优子结构。
设num[i,j]表示串s[i..j]所表示的数字,动态规划的转移方程为f[i,j]=
{f[p,j-1]*num[p+1,i]},初始时有f[i,0]=num[1,i]。
constmax1=30;
max2=20;
typearr1=array[1..max1,0..max2]oflongint;
arr2=array[1..max1]oflongint;
varm:
arr1;
num:
arr2;
f:
text;
i,j,k,p,q,l,n:
st:
string;
code:
integer;
functionnumber(a,b:
integer):
vari,j,m:
m:
j:
=bdowntoadobegin
=m+num[i]*j;
=j*10;
number:
=m;
fillchar(m,sizeof(m),0);
fillchar(num,sizeof(num),0);
Input:
readln(n,k);
readln(st);
=1tondonum[i]:
=ord(st[i])-ord('
0'
writeln(m[n,k]);
proceduremain;
varlin,max:
=1tondom[i,0]:
=number(1,i);
=2tondobegin
=1to20dobegin
ifj>
i-1thencontinue;
max:
forp:
=i-1downto1dobegin
lin:
=m[p,j-1]*number(p+1,i);
iflin>
maxthenmax:
=lin;
m[i,j]:
=max;
main;
第四题 方格取数
先看游戏者从A到B只走一次的情况。
只能向下或向右走,这隐含了格子之间的拟序关系,可以根据这种关系划分子问题。
走到格(x,y)所得到的最大分值只于前一步在格(x-1,y)或(x,y-1)所得到的最大分值有关,即问题具备最优子结构。
设f[x,y]表示走到格(x,y)所得到的最大分值,data[x,y]表示格(x,y)的分值,动态规划的转移方程为f[x,y]=max{f[x-1,y],f[x,y-1]}+data[x,y];
初始时f[1,1]=data[1,1]。
类似的,对于走两次的情况,设f[i1,j1,i2,j2]表示第一,二条路线分别到格(i1,j1),(i2,j2)时得到的最大分值。
动态规划转移方程为
f[i1,j1,i2,j2]=max{f[i1-1,j1,i2,j2],f[i1,j1-1,i2,j2],f[i1,j1,i2-1,j2],f[i1,j1,i2,j2-1]}+data[i1,j1]+data[i2,j2](当(i1,j1)=(i2,j2)时只加一次)),初始时f[1,1,1,1]=data[1,1]。
programget_number;
constmaxn=10;
typearraytype=array[0..maxn,0..maxn]oflongint;
vari,j,k,n,i1,i2,j1,j2:
data:
arraytype;
sum:
array[0..maxn,0..maxn,0..maxn,0..maxn]oflongint;
functionmax(x,y:
longint):
ifx>
ythenmax:
=xelsemax:
=y;
end;
=1tomaxndo
=1tomaxndodata[i,j]:
readln(i,j,k);
data[i,j]:
until(i=0)and(j=0)and(k=0);
fillchar(sum,sizeof(sum),0);
fori1:
forj1:
fori2:
forj2:
ifsum[i1-1,j1,i2-1,j2]>
sum[i1,j1,i2,j2]
thensum[i1,j1,i2,j2]:
=sum[i1-1,j1,i2-1,j2];
ifsum[i1-1,j1,i2,j2-1]>
=sum[i1-1,j1,i2,j2-1];
ifsum[i1,j1-1,i2-1,j2]>
=sum[i1,j1-1,i2-1,j2];
ifsum[i1,j1-1,i2,j2-1]>
=sum[i1,j1-1,i2,j2-1];
sum[i1,j1,i2,j2]:
=sum[i1,j1,i2,j2]+data[i1,j1];
if(i1<
i2)or(j1<
j2)
=sum[i1,j1,i2,j2]+data[i2,j2];
Maxscore='
sum[n,n,n,n]);
第五题 数的划分
设f[i,j](i>
=j)表示将数i分成j份的方法总数,分两种情况,一是划分后最小的数为1,这种情况包含的方法总数为f[i-1,j-1],一是划分后最小的数大于1,设a1..aj为这种情况下的一种划分,且ai<
=ai+1(1<
=i<
j),则a1-1..aj-1对应于将数i-j分为j份的一种划分,且这种对应是一一对应,所以这种情况包含的方法总数为f[i-j,j]。
programdp;
constoutputfile='
;
vari,j,k,m,n:
integer;
f:
array[0..200,0..7]oflongint;
read(n,m);
f[0,0]:
=1tomdo
ifi>
=jthenf[i,j]:
=f[i-j,j]+f[i-1,j-1];
assign(output,outputfile);
writeln(f[n,m]);
end.
第六题 统计单词个数
设g[i,l]表示将字串st[1..l]分成i份所能得到的最大单词个数,f[p,ll]表示字串st[p..ll]中包含的最大单词个数。
将字串st[1..l]分成i份的最优解(设其中第i份为st[s..l])中一定包含了子问题将字串st[1..s]分成i-1份的最优解,问题具备最优子结构。
转移方程为g[i,ll]=
{g[i-1,s]+f[s+1,ll]}。
如何求f[p,ll]呢?
若有两个单词在串st中占有同一个首字母,显然应该选长度小的一个。
可以设wp[i]表示st中以s[i]开头的单词的最小长度,若没有这样的单词,则wp[i]:
串st[p..ll]中包含的单词个数即为
op(wp[i]+i-1<
=ll),函数op(命题I)当I为真时值为1,I为假时值为0。
若先求f[p+1,ll]后求f[p,ll],可以有f[p,ll]=f[p+1,ll]+op(wp[p]+p-1<
=ll)。
由于当前阶段的状态只于上一阶段有关,实现时运用了滚动数组。
{$A+,B-,D-,E+,F-,G+,I-,L+,N-,O-,P-,Q-,R-,S-,T-,V+,X+}
{$M16384,0,655360}
const
maxn=200;
{maxl=20;
{maxword'
slength}
type
ftype=array[0..1,0..maxn]ofinteger;
var
map:
array[1..maxn,1..maxn]ofbyte;
ff:
text;
nn,k,l,i,maxll:
procedureInit;
i,j,p,o,ll:
s,t,word:
string;
ch:
char;
readln(ff,p,k);
s:
='
=1topdobegin
read(ff,ch);
=s+ch;
readln(ff);
l:
=length(s);
readln(ff,p);
fillchar(map,sizeof(map),0);
maxll:
readln(ff,word);
whileword[length(word)]='
dodelete(word,length(word),1);
=pos(word,t);
o:
ll:
=length(word);
ifll>
maxllthenmaxll:
=ll;
whilej>
0dobegin
map[o+j,ll]:
delete(t,1,j);
=o+j;
=1toldo
=2tol-i+1do
if(map[i,j]=0)and(map[i,j-1]=1)
thenmap[i,j]:
procedureMain;
i,j,i1,i2,s,ll,o,p,p1,p2,lw
:
g:
array[0..1,0..maxn]ofinteger;
ftype;
fillchar(g,sizeof(g),0);
=1tokdobegin
i1:
=imod2;
i2:
=1-i1;
fillchar(g[i2],sizeof(g[i2]),0);
fors:
=i-1tol-k+i-1dobegin
{ifl-k+i-s>
maxll
theno:
=maxll
else}o:
=l-k+i;
fillchar(f,sizeof(f),0);
=s+1toodobegin
p1:
=pmod2;
p2:
=1-p1;
fillchar(f[p2],sizeof(f[p2]),0);
forll:
=ptoodobegin
iff[p2,ll-1]>
f[p1,ll]
thenf[p2,ll]:
=f[p2,ll-1]
elsef[p2,ll]:
=f[p1,ll];
if(map[p,ll-p+1]>
0)and(f[p2,ll]<
f[p1,ll]+1)
=f[p1,ll]+1;
ifg[i2,ll]<
f[p2,ll]+g[i1,s]
theng[i2,ll]:
=f[p2,ll]+g[i1,s]
writeln(g[i2,l]);
assign(ff,'
input3.dat'
reset(ff);
readln(ff,nn);
=1tonndobegin
Init;
Main;
close(ff);
第七题 低价买入,更低价买入
本题实际上是给出数列a1..an,求最长非递增序列的长度,我们可以用f[k]表示数列a1..ak中以ak结尾的最长非递增序列的长度,题目所求即为max{f[1..n]}。
=a[k]) 初始时,f[0]=0,a[0]=-maxint.
VARN:
WORD;
PRICE:
ARRAY[1..5000]OFREAL;
LIST:
ARRAY[1..
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 动态规划解析 浅谈记忆化搜索 动态 规划 解析 浅谈 记忆 搜索