1、数塔问题(tower.pas)
设有一个三角形的数塔,如下图所示。顶点结点称为根结点,每个结点有一个整数数值。从顶点出发,在每一结点可以选择向左走或是向右走,一起走到底层,要求找出一条路径,使路径上的值最大。
【样例输入】tower.in
5       {数塔层数}
13
11   8
12   7    26
6   14    15    8
12   7    13   24    11
【样例输出】tower.out
max=86
【参考程序】
//By LYLtim

uses math;
var n,i,j:byte;
    a:array[1..10,1..10]of word;
    f:array[1..10,1..10]of word;
begin
    assign(input,'tower.in');reset(input);
    assign(output,'tower.out');rewrite(output);
    readln(n);
    for i:=1 to n do
        begin
            for j:=1 to i do
                read(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 do
        for j:=1 to i do
            f[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.in                        
389 207 155 300 299 170 158 65    
【输出样例】missile.out
6(最多能拦截的导弹数)
2(要拦截所有导弹最少要配备的系统数)
【参考程序】
//By LYLtim

type node=record
            h,lens:word;
          end;

var n,i,j,maxl,num,minsys:word;
    mis:array[word]of node;
    sysl:array[word]of word;

begin
    assign(input,'missile.in');reset(input);
    assign(output,'missile.out');rewrite(output);
    while not eoln do
        begin
            inc(n);
            read(mis[n].h);
            mis[n].lens:=1;
        end;
    for i:=2 to n do
        begin
            for j:=1 to i-1 do
                if(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>maxl then maxl:=mis[i].lens;
        end;
    writeln(maxl);
    num:=1;
    sysl[0]:=maxint;
    sysl[1]:=mis[1].h;
    for i:=2 to n do
        begin
            minsys:=0;
            for j:=1 to num do
                if(sysl[j]>=mis[i].h)and(sysl[j]<sysl[minsys])then minsys:=j;
            if minsys=0 then begin inc(num); sysl[num]:=mis[i].h; end
            else sysl[minsys]:=mis[i].h;
        end;
    writeln(num);
    close(input);close(output);
end.

3、最短路径(short.pas)
在下图中找出从起点到终点的最短路径。

  动态规划题目及其代码 By LYLtim - LYLtim - LYLtim的163博客

【样例输入】short.in
7
0 3 5 0 0 0 0
0 0 0 7 8 6 0
0 0 0 0 4 5 0
0 0 0 0 0 0 4
0 0 0 0 0 0 7
0 0 0 0 0 0 6
0 0 0 0 0 0 0
【样例输出】short.out
minlong=14
1 2 4 7
【参考程序】
//By LYLtim

type node=record
            dis,pre:word;
          end;

var n,i,j,x:byte;
    map:array[byte,byte]of word;
    a:array[word]of node;

begin
    assign(input,'short.in');reset(input);
    assign(output,'short.out');rewrite(output);
    readln(n);
    for i:=1 to n do
        begin
            a[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 do
        for j:=n downto i+1 do
            if(map[i,j]>0)and(a[j].dis<maxint)and(a[j].dis+map[i,j]<a[i].dis)then
                with 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 do
        begin
            write(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.in
6
5 10 20 5 4 5
1 2
1 4
2 4
3 4
4 5
4 6
5 6
0 0
【输出样例】Mine.out
3-4-5-6
34
【参考程序】
//By LYLtim

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;
begin
    assign(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)do
        begin
            g[x,y]:=true;
            readln(x,y);
        end;
    close(input);
end;{init}

procedure work;
var i,j:byte;
begin
    fillchar(f,sizeof(f),0);
    f[n]:=w[n];
    fillchar(next,sizeof(next),0);
    for i:=n-1 downto 1 do
        begin
            for j:=i+1 to n do
                if(g[i,j])and(f[j]>f[i])then
                    begin
                        f[i]:=f[j];
                        next[i]:=j;
                    end;
            inc(f[i],w[i]);
        end;
    max:=0;
    for i:=1 to n do
        if f[i]>max then
            begin
                max:=f[i];
                start:=i;
            end;
end;{work}

procedure print;
begin
    assign(output,'mine.out');rewrite(output);
    write(start);
    while next[start]<>0 do
        begin
            write('-',next[start]);
            start:=next[start];
        end;
    writeln;
    writeln(max);
    close(output);
end;{print}

begin{main}
    init;
    work;
    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):要在连续的若干行里给出每一组数据在安全条件下能够开通的最大航线数目。
【输入输出样例】

Ship.in

30   4

5

4   5

2   4

5   2

1   3

3   1

Ship.out

3

【参考程序】
//By LYLtim

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;
begin
    assign(input,'ship.in');reset(input);
    readln(x,y);
    readln(n);
    for i:=1 to n do
        with a[i] do
            begin
                readln(c,d);
                l:=1;
            end;
    close(input);
end;{init}

procedure qsort(l,r:word);
var pl,pr,m:word;
    t:node;
begin
    pl:=l;pr:=r;m:=a[(l+r)>>1].c;
    repeat
        while a[pl].c<m do inc(pl);
        while a[pr].c>m do dec(pr);
        if pl<=pr then
            begin
                t:=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;
begin
    for i:=2 to n do
        begin
            for j:=1 to i-1 do
                if(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;
begin
    assign(output,'ship.out');rewrite(output);
    writeln(maxl);
    close(output);
end;{print}

begin{main}
    init;
    qsort(1,n);
    work;
    print;
end.

6、骑士游历问题(knight.pas)
   【详见教程】
【参考程序】
//By LYLtim

const dx:array[1..4]of shortint=(1,2,2,1);
      dy:array[1..4]of shortint=(2,1,-1,-2);

var n,m,x1,y1,x2,y2,i,j,k:byte;
    x,y:shortint;
    map:array[1..50,1..50]of int64;

begin
    assign(input,'knight.in');reset(input);
    assign(output,'knight.out');rewrite(output);
    fillchar(map,sizeof(map),0);
    readln(n,m,x1,y1,x2,y2);
    map[x1,y1]:=1;
    for i:=x1 to x2 do
        for j:=1 to m do
            for k:=1 to 4 do
                begin
                    x:=i+dx[k];y:=j+dy[k];
                    if(x<=x2)and(y in[1..m])then
                        inc(map[x,y],map[i,j]);
                end;
    writeln(map[x2,y2]);
    close(input);close(output);
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.in
1 1 0   0   0   0
【输出样例】weight.out
Total=3,表示可以称出1g,2g,3g三种不同的重量
【参考程序】
//By LYLtim

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;
begin
    assign(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 do
        for j:=1 to w[0] do
            for k:=1 to n[i] do
                begin
                    nw:=w[j]+wt[i]*k;
                    if not vis[nw] then
                        begin
                            vis[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),每个物品有一个体积(正整数)。要求从n个物品中,任取若干个装入箱内,使箱子的剩余空间为最小。
【输入格式】
箱子的容量v
    物品数n
接下来n行,分别表示这n个物品的体积
【输出格式】
    箱子剩余空间
【输入样例】boxes.in
24
6
8
3
12
7
9
7
【输出样例】boxes.out
0
【参考程序】
//By LYLtim

var v,j,cost:word;
    n,i:byte;
    c:array[1..30]of word;
    f:array[0..20000]of boolean;
begin
    assign(input,'boxes.in');reset(input);
    assign(output,'boxes.out');rewrite(output);
    readln(v);
    readln(n);
    for i:=1 to n do readln(c[i]);
    close(input);
    fillchar(f,sizeof(f),false);
    f[0]:=true;
    for i:=1 to n do
        for j:=v downto c[i] do
            if f[j-c[i]] then f[j]:=true;
    cost:=v;
    while not f[cost] do dec(cost);
    writeln(v-cost);
    close(output);
end.

9、合唱队形(Chorus.pas)
N位同学站成一排,音乐老师要请其中的(N-K)位同学出列,使得剩下的K位同学排成合唱队形。合唱队形是指这样的一种队形:设K位同学从左到右依次编号为1, 2, …, K,他们的身高分别为T1, T2, …, TK,则他们的身高满足T1 < T2 < … < Ti , Ti > Ti+1 > … > TK (1≤i≤K)。
已知所有N位同学的身高,计算最少需要几位同学出列,可以使得剩下的同学排成合唱队形。
【输入文件】
输入文件chorus.in的第一行是一个整数N(2 ≤ N ≤ 100),表示同学的总数。第二行有n个整数,用空格分隔,第i个整数Ti(130 ≤ Ti ≤ 230)是第i位同学的身高(厘米)。
【输出文件】
输出文件chorus.out包括一行,这一行只包含一个整数,就是最少需要几位同学出列。
【样例输入】chorus.in
8
186 186 150 200 160 130 197 220
【样例输出】chorus.out
4
【参考程序】
//By LYLtim

type node=record h,ups,downs:byte; end;
var n,i,j,max:byte;
    stu:array[1..100]of node;
begin
    assign(input,'chorus.in');reset(input);
    assign(output,'chorus.out');rewrite(output);
    readln(n);
    for i:=1 to n do
        begin
            stu[i].ups:=1;stu[i].downs:=1;
            read(stu[i].h);
        end;
    close(input);
    for i:=2 to n do
        for j:=1 to i-1 do
            if(stu[j].h<stu[i].h)and(stu[j].ups+1>stu[i].ups)then
                stu[i].ups:=stu[j].ups+1;
    for i:=n-1 downto 1 do
        for j:=i+1 to n do
            if(stu[j].h<stu[i].h)and(stu[j].downs+1>stu[i].downs)then
                stu[i].downs:=stu[j].downs+1;
    max:=0;
    for i:=1 to n do if stu[i].ups+stu[i].downs>max then max:=stu[i].ups+stu[i].downs;
    writeln(n-max+1);
    close(output);
end.

10、橱窗布置(Flower.pas)
   【详见教程】
【参考程序】
//By LYLtim

var f,v:byte;
    a:array[1..100,1..100]of shortint;
    opt:array[0..100,0..100]of longint;
    b:array[0..100,0..100]of byte;
    c:array[1..100]of byte;

procedure init;
var i,j:byte;
begin
    assign(input,'flower.in');reset(input);
    readln(f,v);
    for i:=1 to f do
   begin
    for j:=1 to v do read(a[i,j]);
    readln;
   end;
    close(input);
end;{init}

procedure work;
var i,j:byte;
begin
    for i:=1 to f do
        for j:=i to i+v-f do
            if(opt[i-1,j-1]+a[i,j]>opt[i,j-1])or(j=1)then
                begin opt[i,j]:=opt[i-1,j-1]+a[i,j]; b[i,j]:=j; end
            else begin opt[i,j]:=opt[i,j-1]; b[i,j]:=b[i,j-1]; end;
end;{work}

procedure print;
var i,j:byte;
begin
    assign(output,'flower.out');rewrite(output);
    writeln(opt[f,v]);
    j:=v;
    for i:=f downto 1 do
        begin
            c[i]:=b[i,j];
            j:=c[i]-1;
        end;
    for i:=1 to f-1 do write(c[i],' ');
    writeln(c[f]);
    close(output);
end;{print}

begin{main}
    init;
    work;
    print;
end.

posted on 2011-08-05 10:56  shallyzhang  阅读(916)  评论(0)    收藏  举报