ACM经典算法(5)

2019-01-19 12:34

程序如下:

var

a:array[1..100,1..2]of integer; k:array[1..2]of integer; b:array[0..100]of integer; f:text;

t,m,max,i,j:integer;

procedure try(k,t1,s:integer); var

i:integer; begin

if s>max then max:=s; if t1

if a[i,1]<=t1 then begin b[k]:=i;try(k+1,t1-a[i,1],s+a[i,2]);end; end;

begin

assign(f,'medic1.in'); reset(f);

readln(f,t,m); for i:=1 to m do

readln(f,a[i,1],a[i,2]); close(f);b[0]:=0; a[m+1,1]:=a[1,1]; for i:=2 to m do

if a[m+1,1]>a[I,1] then a[m+1,1]:=a[I,1]; {a[m+1,1]存放最小时间值} for i:=1 to m-1 do for j:=i+1 to m do

if a[i,2]/a[i,1]

第七次课 深搜(4)

一、 棋子控制棋盘

5*5的棋盘上的每棵棋子都可以控制它的上下左右不能放棋子,求可以控制整个棋盘的最少棋子数。

const

c:array[1..5,1..2]of integer=((0,1),(0,-1),(1,0),(-1,0),(0,0)); var

a,b:array[0..6,0..6]of integer; min:integer;

procedure lookup(var x,y:integer); var

i,j:integer; begin

for i:=1 to 5 do for j:=1 to 5 do if a[i,j]=0 then begin

x:=i;y:=j;exit; end; x:=0 end;

procedure try(k:integer); var

x,y,xx,yy,i,j:integer; begin

if min<=k-1 then exit; lookup(x,y);

if x=0 then begin min:=k-1;b:=a;exit;end; for i:=1 to 5 do begin xx:=x+c[i,1]; yy:=y+c[i,2];

if (xx>0)and(xx<6)and(yy>0)and(yy<6)then begin

inc(a[xx,yy],10); for j:=1 to 4 do

inc(a[xx+c[j,1],yy+c[j,2]]); try(k+1);

for j:=1 to 4 do

dec(a[xx+c[j,1],yy+c[j,2]]); dec(a[xx,yy],10); end; end; end; begin

fillchar(a,sizeof(a),0); min:=15; try(1);

writeln(min);

end.

inc(a[xx,yy],10); for j:=1 to 4 do

inc(a[xx+c[j,1],yy+c[j,2]]); try(k+1);

for j:=1 to 4 do

dec(a[xx+c[j,1],yy+c[j,2]]); dec(a[xx,yy],10); end; end; end; begin

fillchar(a,sizeof(a),0); min:=8; try(1);

writeln(min); end.

二、均分数据

源程序名 data.???(pas|c|bas) 输入文件名 data.in 输出文件名 data.out 【问题描述】

已知N个正整数:A1、A2、……、An 。今要将它们分成M组(X1,X2,……,Xm),使得各组数据的数值和最平均,即各组的和与各组和的平均值的差的绝对值的和最小。公式如下:

X=(X1+X2+……+Xm)/M

Y=|X1-X|+|X2-X|+……+|Xm-X|

X是各组数据和的平均值,Xi为第i组数据的数值和。即求所有分法中Y值的最小值。 【输入文件】

输入文件data.in包括:

第一行是两个整数,表示N,M的值(N是整数个数,M是要分成的组数)

第二行有N个整数,表示A1、A2、……、An。整数的范围是1--50。 (同一行的整数间用空格分开) 【输出文件】

输出文件data.out包括一行,这一行只包含一个数,表示各组的和与各组和的平均值的差的绝对值的和的最小值(四舍五入后保留2位小数)。

【样例】

若输入文件data.in中的内容为:

6 3

1 2 3 4 5 6

则输出文件data.out中的内容应为 0. 00

(1和6、2和5、3和4分别为一组) 【问题规模】

50%的数据2<=N<=10,M=2

100%的数据M<=N <= 20,2<=M<=5

算法一:

以每个数为出发点,搜索它放的组别。 var

a,b:array[1..20] of integer; n,m,i:integer; p,min:real; f:text; c:char;

procedure try(k:integer); var i:integer; s:real; begin

if k>n then begin

s:=0;

for i:=1 to m do s:=s+abs(b[i]-p); if s

b[i]:=b[i]+a[k]; try(k+1);

b[i]:=b[i]-a[k]; end; end; begin

assign(f,'data.in'); reset(f);

readln(f,n,m);

for i:=1 to n do read(f,a[i]); close(f); p:=0;

for i:=1 to n do p:=p+a[i]; p:=p/m;

min:=10000000;

fillchar(b,sizeof(b),0); try(1);

assign(f,'data.out'); rewrite(f);

writeln(f,min:4:2); close(f); end.

算法二:

以组为出发点,搜索它内部放的数。组内是无序的,各数之间是组合问题;组间也是无序的,也是组合问题。组的控制只须把未被使用的第一个数定为该组的第一个元素,以后元素按组合的方式搜索。 var a:array[1..100] of integer; n,m,i,s,j:integer;

b:array[1..100] of boolean; c:array[1..30,1..100] of integer; f:text; x,y:real;

procedure try(k,l,s,p:integer;t:real); var i:integer; begin

if k<2 then

begin

if y>t+abs(s-x) then y:=t+abs(s-x); exit; end;

if y<=t+abs((p+s)/k-x)*k then exit; if l=1 then

begin

for i:=1 to n do if b[i] then begin

b[i]:=false; c[k,l]:=i;

try(k-1,1,s-a[i],0,t+abs(p+a[i]-x)); try(k,2,s-a[i],p+a[i],t); c[k,l]:=0; b[i]:=true; break; end; end else begin

for i:=c[k,l-1]+1 to n do


ACM经典算法(5).doc 将本文的Word文档下载到电脑 下载失败或者文档不完整,请联系客服人员解决!

下一篇:全市保障性安居工程实施情况专项督查方案

相关阅读
本类排行
× 注册会员免费下载(下载后可以自由复制和排版)

马上注册会员

注:下载文档有可能“只有目录或者内容不全”等情况,请下载之前注意辨别,如果您已付费且无法下载或内容有问题,请联系我们协助你处理。
微信: QQ: