| 网站首页 | 信息中心 | 下载中心 | 中心论坛 | 信息学竞赛 | 兴趣学习 | 在线课堂 | 
您现在的位置: 高要一中信息中心 >> 信息学竞赛 >> 算法设计 >> 正文 用户登录 新用户注册
[组图]第六章 穷举(枚举)策略(PASCAL)         ★★★ 【字体:
第六章 穷举(枚举)策略(PASCAL)
作者:missyou    文章来源:本站原创    点击数:    更新时间:2008-9-28    

 

6.1 穷举策略的概念  

所谓枚举法,指的是从可能的解的集合中一一枚举各元素, 用题目给定的检验条件判定哪些是无用的,哪些是有用的。能使命题成立,即为其解。

有些问题可以用循环语句和条件语句直接求解,有些问题用循环求解时循环次数太多,无法编写程序,怎么办?下面是用“千军万马过独木桥,适者存”的方式实现穷举策略的。

6.2 典型例题与习题

例1.将2n个0和2n个1,排成一圈。从任一个位置开始,每次按逆时针的方向以长度为n+1的单位进行数二进制数。要求给出一种排法,用上面的方法产生出来的2n+1个二进制数都不相同。

例如,当n=2时,即22个0和22个1排成如下一圈:

比如,从A位置开始,逆时针方向取三个数000,然后再从B位置上开始取三个数001,接着从C开始取三个数010,...可以得到000,001,010,101,011,111,110,100共8个二进制数且都不相同。

程序说明:

以n=4为例,即有16个0,16个1,数组a用以记录32个0,1的排法,数组b统计二进制数出现的可能性。

  程序清单

  PROGRAM NOI00;
  VAR
   A    :ARRAY[1..36] OF 0..1
   B    :ARRAY[0..31] OF INTEGER;
   I,J,K,S,P:INTEGER;
   BEGIN
    FOR I:=1 TO 36 DO  A[I]:=0;
     FOR I:=28 TO 32 DO  A[I]:=1;
    P:=1;  A[6]:=1;
    WHILE (P=1) DO
     BEGIN
      J:=27
      WHILE A[J]=1 DO  J:=J-1;
      ( A[J]:=1 )
      FOR I:=J+1 TO 27 DO ( A[i]:=0 )
      FOR I:=0 TO 31 DO B[I]:=0;
      FOR I:=1 TO 32 DO
       BEGIN
       ( S:=0)
        FOR K:=I TO I+4 DO  S:=S*2+A[k];
        ( B[S]:=1 )
       END;
      S:=0;
      FOR I:=0 TO 31 DO  S:=S+B[I];
      IF ( S=32 ) THEN P:=0
     END;
     FOR I:=1 TO 32 DO  FOR J:=I TO I+4 DO  WRITE(A[J]);
   WRITELN
  END.

例2:在AB两个城市之间设有N个路站(如下图中的S1,且N<100),城市与路站之间、路站和路站之间各有若干条路段(各路段数<=20,且每条路段上的距离均为一个整数)
    AB的一条通路是指:从A出发,可经过任一路段到达S1,再从S1出发经过任一路段,…最后到达B。通路上路段距离之和称为通路距离(最大距离<=1000)。当所有的路段距离给出之后,求出所有不同距离的通路个数(相同距离仅记一次)
    例如:下图所示是当N=1时的情况:

AB的通路条数为6,但因其中通路5+5=4+6,所以满足条件的不同距离的通路条数为5

算法说明:本题采用穷举算法。
数据结构:
N:记录AB间路站的个数
          数组D[I0]记录第I-1个到第I路站间路段的个数
              D[I1]D[I2]记录每个路段距离
          数组G记录可取到的距离
程序清单:
program CHU7_6;
var i,j,n,s:integer;
  b:array[0..100] of integer;
  d:array[0..100,0..20] of integer;
  g:array[0..1000] of 0..1;
begin
  readln(n);
  for i:=1 to n+1 do
    begin
      readln(d[i,0]);
      for j:=1 to d[i,0] do read(d[i,j]);
    end;
  d[0,0]:=1;
  for i:=1 to n+1 do b[i]:=1;
  b[0]:=0;
  for i:=1 to 1000 do g[i]:=0;
  while        b[0]<>1       do
    begin
      s:=0;
      for i:=1 to n+1 do
        s:=       s+d[i,b[i]];     
        g[s]:=1;j:=n+1;
      while          b[j]=d[j,0]        do j:=j-1;
      b[j]:=b[j]+1;
      for i:=j+1 to n+1 do b[i]:=1;
    end;
  s:=0;
  for i:=1 to 1000 do
           s:=s+g[i];      
  writeln(s);readln;
end.

练习:

1。问题描述:将n个整数分成k组(k≤n,要求每组不能为空),显然这k个部分均可得到一个各自的和s1,s2,……sk,定义整数P为:

P=(S1-S2)2+(S1一S3)2+……+(S1-Sk)2+(s2-s3)2+……+(Sk-1-Sk)2

问题求解:求出一种分法,使P为最小(若有多种方案仅记一种〉

程序说明:

数组:a[1],a[2],...A[N]存放原数

s[1],s[2],...,s[K]存放每个部分的和

b[1],b[2],...,b[N]穷举用临时空间

d[1],d[2],...,d[N]存放最佳方案

程序:

program exp4;

Var i,j,n,k : integer;

a :array [1..100] of integer;

b,d:array [0..100] of integer;

s :array[1..30] of integer;

begin

readln(n,k);

for I:=1 to n do read(a[I]);

for I:=0 to n do b[I]:=1;

cmin:=1000000;

while (b[0]=1) do

begin

    for I:=1 to k do       

for I:=1 to n do

         

sum:=0;

for I:=1 to k-1 do

for j:=      

sum:=sum+(s[I]-s[j])*(s[I]-s[j]);

if         then

begin

cmin:=sum;

for I:=1 to n do d[I]:=b[I];

end;

j:=n;

while           do j:=j-1;

b[j]:=b[j]+1;

for I:=j+1 to n do          

end;

writeln(cmin);

for I:=1 to n do write(d[I]:40);

writeln;

end.

2.问题描述:有n种基本物质(n≤10),分别记为P1,P2,……,Pn,用n种基本物质构造物品,这些物品使用在k个不同地区(k≤20),每个地区对物品提出自己的要求,这些要求用一个n

位的数表示1α2……αn,其中:

αi =1表示所需物质中必须有第i种基本物质

=-1表示所需物质中必须不能有第i种基本物质r

=0无所谓

问题求解:当k个不同地区要求给出之后,给出一种方案,指出哪些物质被使用,哪些物质不被使用。

程序说明:数组b[1],b[2],...,b[nJ表示某种物品

a[1..k,1..n]记录k个地区对物品的要求,其中:

a[I,j]=1表示第i个地区对第j种物品是需要的

a[i,j]=0表示第i个地区对第j种物品是无所谓的

a[i,j]=-1表示第i个地区对第j种物品是不需要的

程序:

program gxp2;

Var i, j ,k, n :integer;

p:boolean;

b :array [0..20] of 0..1;

a :array[1..20,1..10]d integer;

begin

readln(n,k);

for i:=1 to k do

begin

for j:=1 to n do read(a[i,j]);

readln;

end;

for i:=O to n do b[i]:=0;

p:=true;

while               do

begin

j:=n;

while  b[j]=1 do j:=j-1;

        

for i:=j+1 to n do b[I]:=0;

for i:=1 to k do

for j :=1to n do

if( a[i,j]=1 ) and (b[j]=0) or               

then p:=true;

end;

if           

then writeln('找不到!‘)

else for i:=1 to n do

if (b[i]=1) then writeln('物质',I,需要')

else writeln('物质',i,'不需要');

end.

 

文章录入:missyou    责任编辑:missyouadmin 
  • 上一篇文章:

  • 下一篇文章: 没有了
  • 发表评论】【加入收藏】【告诉好友】【打印此文】【关闭窗口
    最新热点 最新推荐 相关文章
    没有相关文章
      网友评论:(只显示最新10条。评论内容只代表网友观点,与本站立场无关!)