动态规划题目及其代码By LYLtim1、数塔问题(tower.pas)设有一个三角形的数塔,如下图所示。
顶点结点称为根结点,每个结点有一个整数数值。
从顶点出发,在每一结点可以选择向左走或是向右走,一起走到底层,要求找出一条路径,使路径上的值最大。
【样例输入】tower.in5 {数塔层数}1311 812 7 266 14 15 812 7 13 24 11【样例输出】tower.outmax=86【参考程序】uses math;var n,i,j:byte;a:array[1..10,1..10]of word;f:array[1..10,1..10]of word;beginassign(input,'tower.in');reset(input);assign(output,'tower.out');rewrite(output);readln(n);for i:=1 to n dobeginfor j:=1 to i doread(a[i,j]);readln;end;fillchar(f,sizeof(f),0);for i:=1 to n do f[n,i]:=a[n,i];for i:=n-1 downto 1 dofor j:=1 to i dof[i,j]:=max(f[i+1,j],f[i+1,j+1])+a[i,j];writeln('max=',f[1,1]);close(input);close(output);end.2、拦截导弹(missile.pas)某国为了防御敌国的导弹袭击,发展出一种导弹拦截系统。
但是这种导弹拦截系统有一个缺陷:虽然它的第一发炮弹能够到达任意的高度,但是以后每一发炮弹都不能高于前一发的高度。
某天,雷达捕捉到敌国的导弹来袭。
由于该系统还在试用阶段,所以只有一套系统,因此有可能不能拦截所有的导弹。
输入导弹依次飞来的高度(雷达给出的高度数据是不大于30000的正整数),计算这套系统最多能拦截多少导弹,如果要拦截所有导弹最少要配备多少套这种导弹拦截系统。
【样例输入】missile.in389 207 155 300 299 170 158 65【输出样例】missile.out6(最多能拦截的导弹数)2(要拦截所有导弹最少要配备的系统数)【参考程序】type node=recordh,lens:word;end;var n,i,j,maxl,num,minsys:word;mis:array[word]of node;sysl:array[word]of word;beginassign(input,'missile.in');reset(input);assign(output,'missile.out');rewrite(output);while not eoln dobegininc(n);read(mis[n].h);mis[n].lens:=1;end;for i:=2 to n dobeginfor j:=1 to i-1 doif(mis[j].h>mis[i].h)and(mis[j].lens+1>mis[i].lens)then mis[i].lens:=mis[j].lens+1;if mis[i].lens>maxlthen maxl:=mis[i].lens;end;writeln(maxl);num:=1;sysl[0]:=maxint;sysl[1]:=mis[1].h;for i:=2 to n dobeginminsys:=0;for j:=1 to num doif(sysl[j]>=mis[i].h)and(sysl[j]<sysl[minsys])then minsys:=j;if minsys=0 thenbegin inc(num); sysl[num]:=mis[i].h; endelse sysl[minsys]:=mis[i].h;end;writeln(num);close(input);close(output);end.3、最短路径(short.pas)在下图中找出从起点到终点的最短路径。
【样例输入】short.in70 3 5 0 0 0 00 0 0 7 8 6 00 0 0 0 4 5 00 0 0 0 0 0 40 0 0 0 0 0 70 0 0 0 0 0 60 0 0 0 0 0 0【样例输出】short.outminlong=141 2 4 7【参考程序】type node=recorddis,pre:word;end;var n,i,j,x:byte;map:array[byte,byte]of word;a:array[word]of node;beginassign(input,'short.in');reset(input);assign(output,'short.out');rewrite(output);readln(n);for i:=1 to n dobegina[i].dis:=maxint;for j:=1 to n do read(map[i,j]);end;close(input);a[n].dis:=0;for i:=n-1 downto 1 dofor j:=n downto i+1 doif(map[i,j]>0)and(a[j].dis<maxint)and(a[j].dis+map[i,j]<a[i].dis)then while a[i] do begin dis:=a[j].dis+map[i,j]; pre:=j; end;writeln('dis=',a[1].dis);x:=1;while a[x].pre<>0 dobeginwrite(x,' ');x:=a[x].pre;end;writeln(x);close(output);end.4、挖地雷(Mine.pas)在一个地图上有N个地窖(N<=200),每个地窖中埋有一定数量的地雷。
同时,给出地窖之间的连接路径,并规定路径都是单向的。
某人可以从任一处开始挖地雷,然后沿着指出的连接往下挖(仅能选择一条路径),当无连接时挖地雷工作结束。
设计一个挖地雷的方案,使他能挖到最多的地雷。
【输入格式】N {地窖的个数}W1,W2,……WN{每个地窖中的地雷数} X1,Y1 {表示从X1可到Y1}X2,Y2……0 ,0 {表示输入结束}【输出格式】K1——K2——……——Kv {挖地雷的顺序} MAX {最多挖出的地雷数} 【输入样例】Mine.in65 10 20 5 4 51 21 42 43 44 54 65 60 0【输出样例】Mine.out3-4-5-634【参考程序】var n,start:byte;w:array[1..200]of word;g:array[1..200,1..200]of boolean;f:array[1..200]of longword;next:array[1..200]of byte;max:longword;procedure init;var i,x,y:byte;beginassign(input,'mine.in');reset(input);readln(n);for i:=1 to n do read(w[i]);readln;readln(x,y);fillchar(g,sizeof(g),false);while(x<>0)and(y<>0)dobeging[x,y]:=true;readln(x,y);end;close(input);end;{init}procedure work;var i,j:byte;beginfillchar(f,sizeof(f),0);f[n]:=w[n];fillchar(next,sizeof(next),0);for i:=n-1 downto 1 dobeginfor j:=i+1 to n doif(g[i,j])and(f[j]>f[i])thenbeginf[i]:=f[j];next[i]:=j;end;inc(f[i],w[i]);end;max:=0;for i:=1 to n doif f[i]>max thenbeginmax:=f[i];start:=i;end;end;{work}procedure print;beginassign(output,'mine.out');rewrite(output);write(start);while next[start]<>0 dobeginwrite('-',next[start]);start:=next[start];end;writeln;writeln(max);close(output);end;{print}begin{main}init;print;end.5、轮船问题(ship.pas)【问题描述】某国家被一条河划分为南北两部分,在南岸和北岸总共有N对城市,每一城市在对岸都有唯一的友好城市,任何两个城市都没有相同的友好城市。
每一对友好城市都希望有一条航线来往,于是他们向政府提出了申请。
由于河终年有雾。
政府决定允许开通的航线就互不交叉(如果两条航线交叉,将有很大机会撞船)。
兴建哪些航线以使在安全条件下有最多航线可以被开通。
【输入格式】输入文件(ship.in):包括了若干组数据,每组数据格式如下:第一行两个由空格分隔的整数x,y,10〈=x〈=6000,10〈=y〈=100。
x 表示河的长度而y表示宽。
第二行是一个整数N(1<=N<=5000),表示分布在河两岸的城市对数。
接下来的N行每行有两个由空格分隔的正数C,D(C、D〈=x〉,描述每一对友好城市与河起点的距离,C表示北岸城市的距离而D表示南岸城市的距离。
在河的同一边,任何两个城市的位置都是不同的。
【输出格式】输出文件(ship.out):要在连续的若干行里给出每一组数据在安全条件下能够开通的最大航线数目。
【输入输出样例】30 454 52 45 21 33 1Ship.out3【参考程序】type node=record c,d,l:word; end; var x,n:word;y:longword;a:array[1..5000]of node;maxl:word;procedure init;var i:word;beginassign(input,'ship.in');reset(input);readln(x,y);readln(n);for i:=1 to n dowith a[i] dobeginreadln(c,d);l:=1;end;close(input);end;{init}procedure qsort(l,r:word);var pl,pr,m:word;t:node;beginpl:=l;pr:=r;m:=a[(l+r)>>1].c;repeatwhile a[pl].c<m do inc(pl);while a[pr].c>m do dec(pr);if pl<=pr thenbegint:=a[pl];a[pl]:=a[pr];a[pr]:=t;inc(pl);dec(pr);end;until pl>pr;if pl<r then qsort(pl,r);if pr>l then qsort(l,pr);end;{qsort}procedure work;var i,j:word;beginfor i:=2 to n dobeginfor j:=1 to i-1 doif(a[j].d<a[i].d)and(a[j].l+1>a[i].l)then a[i].l:=a[j].l+1;if a[i].l>maxl then maxl:=a[i].l;end;end;{work}procedure print;beginassign(output,'ship.out');rewrite(output);writeln(maxl);close(output);end;{print}begin{main}init;qsort(1,n);work;print;end.7、砝码称重(weight.pas)设有1g,2g,3g,5g,10g,20g的砝码各若干枚(其总重≤1000g),要求:【输入格式】a1 a2 a3 a4 a5 a6(表示1g砝码有a1个,2g砝码有a2个,....20g砝码有a6个)【输出格式】Total=N (N表示用这些砝码能称出的不同重量的个数,但不包括一个砝码也不用的情况)【输入样例】weight.in1 1 0 0 0 0【输出样例】weight.outTotal=3,表示可以称出1g,2g,3g三种不同的重量【参考程序】const wt:array[1..6]of shortint=(1,2,3,5,10,20); var n:array[1..6]of word;vis:array[0..1000]of boolean;w:array[0..1000]of word;i,j,k,nw:word;beginassign(input,'weight.in');reset(input);assign(output,'weight.out');rewrite(output);fillchar(vis,sizeof(vis),false);for i:=1 to 6 do read(n[i]);w[0]:=1;w[1]:=0;for i:=1 to 6 dofor j:=1 to w[0] dofor k:=1 to n[i] dobeginnw:=w[j]+wt[i]*k;if not vis[nw] thenbeginvis[nw]:=true;inc(w[0]);w[w[0]]:=nw;end;end;writeln('Total=',w[0]-1);close(input);close(output);end.8、装箱问题(boxes.pas)有一个箱子容量为v(正整数,0≤v≤20000),同时有n个物品(0<n≤30),每个物品有一个体积(正整数)。