动态规划解析 浅谈记忆化搜索Word文档下载推荐.docx

上传人:b****3 文档编号:17233231 上传时间:2022-11-29 格式:DOCX 页数:28 大小:34.26KB
下载 相关 举报
动态规划解析 浅谈记忆化搜索Word文档下载推荐.docx_第1页
第1页 / 共28页
动态规划解析 浅谈记忆化搜索Word文档下载推荐.docx_第2页
第2页 / 共28页
动态规划解析 浅谈记忆化搜索Word文档下载推荐.docx_第3页
第3页 / 共28页
动态规划解析 浅谈记忆化搜索Word文档下载推荐.docx_第4页
第4页 / 共28页
动态规划解析 浅谈记忆化搜索Word文档下载推荐.docx_第5页
第5页 / 共28页
点击查看更多>>
下载资源
资源描述

动态规划解析 浅谈记忆化搜索Word文档下载推荐.docx

《动态规划解析 浅谈记忆化搜索Word文档下载推荐.docx》由会员分享,可在线阅读,更多相关《动态规划解析 浅谈记忆化搜索Word文档下载推荐.docx(28页珍藏版)》请在冰豆网上搜索。

动态规划解析 浅谈记忆化搜索Word文档下载推荐.docx

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..

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 外语学习 > 韩语学习

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1