一个NOI的算法问题,求救!(50分)

  • 主题发起人 主题发起人 seemestudio
  • 开始时间 开始时间
S

seemestudio

Unregistered / Unconfirmed
GUEST, unregistred user!
有 N 堆纸牌,编号分别为 1,2,…, N。每堆上有若干张,但纸牌总数必为 N 的倍数。可以在任一堆上取若于张纸牌,然后移动。
  移牌规则为:在编号为 1 堆上取的纸牌,只能移到编号为 2 的堆上;在编号为 N 的堆上取的纸牌,只能移到编号为 N-1 的堆上;其他堆上取的纸牌,可以移到相邻左边或右边的堆上。
  现在要求找出一种移动方法,用最少的移动次数使每堆上纸牌数都一样多。
  例如 N=4,4 堆纸牌数分别为:
  ① 9 ② 8 ③ 17 ④ 6
  移动3次可达到目的:
  从 ③ 取 4 张牌放到 ④ (9 8 13 10) -> 从 ③ 取 3 张牌放到 ②(9 11 10 10)-> 从 ② 取 1 张牌放到①(10 10 10 10)。
[输 入]:
  键盘输入文件名。文件格式:
  N(N 堆纸牌,1 <= N <= 100)
  A1 A2 … An (N 堆纸牌,每堆纸牌初始数,l<= Ai <=10000)
[输 出]:
  输出至屏幕。格式为:
  所有堆均达到相等时的最少移动次数。‘
[输入输出样例]
a.in:
 4
 9 8 17 6
屏慕显示:
 3
 
program Project2;
{$APPTYPE CONSOLE}
uses
SysUtils;
type
TNode = record
Num: Integer;
Delta: Integer;
Step: Integer
end;

var
a: array [1..100] of TNode;
n: Integer;
Average: Integer;
i: Integer;
procedure Init;
var
FileName: string;
f: TextFile;
i: Integer;
Sum: Integer;
begin
Write('Input FileName: ');
ReadLn(FileName);
Assign(f, FileName);
Reset(f);
ReadLn(f, n);
Sum:=0;
for i:=1 to ndo
begin
Read(f, a.Num);
Sum:=Sum+a.Num;
a.Delta:=0;
a.Step:=0;
a.Delta:=0
end;
Average:=Sum div n;
a[n].Delta:=a[n].Num-Average;
if a[n].Delta=0 then
a[n].Step:=0
else
a[n].Step:=1;
CloseFile(f)
end;

begin
Init;
for i:=n-1do
wnto 1do
begin
a.Delta:=a[i+1].Delta+a.Num-Average;
if a.Delta=0 then
a.Step:=a[i+1].Step
else
a.Step:=a[i+1].Step+1
end;
Write(a[1].Step);
ReadLn
end.
用动态规划做的,用这孩子虽然效率特高,但总结的不对就错的离奇.
你多测测吧.
 
用二分法吧,
1,先求得每堆的平均后的张数m;2,把所以的堆分成二个部分a1,b1;3,算出aq的总张数add[a1]后,
算出应分得的总张数as[a1],相差多少张就为第一次移的张数同时移动次数加一,相等时不记数。
用递归吧!
 
呵呵,谁在一个劲提前呀?
要是有Bug,就说出来嘛.
 
其实很简单就能解,现在没pascal,一会儿贴程序上来
 
var a:array[1..100] of longint;
s:longint;
step,n,i:integer;
inputfile:string;
begin
readln(inputfile);
assign(input,inputfile);
reset(input);
read(n);
for i:=1 to ndo
read(a);
s:=0;
for i:=1 to ndo
s:=s+a;
s:=s div n;
step:=0;
for i:=1 to n-1do
if a<>s then
begin
a[i+1]:=a[i+1]+s-a;
a:=s;
step:=step+1;
end;
writeln(step);
close(input);
end.
 
另外,纠正一下,这不是NOI的题目,只是NOIP的题目
 
这个题可以用n种方法搞对,没有什么意义。
我当时考试时用Greedy就搞了满分。
 
to ai:
咱两一个从前往后推,一个从后往前推.好象没什么本质区别吧.
另外,你知道此题的出处吗?
 
呵呵,好像是没什么区别,不过你好像有浪费空间之嫌:)
 
哎,在下是为了套动态规划的公式呀.
 
还有公式啊?
没学过
比赛在即,我得好好补课了
 
呵呵,也不能叫公式.只是习惯而已.就象我写的所有深度优先都有如下片段.
while Top>0do
begin
while Stack[Top].d<xxdo
begin
...
end;
Dec(Top)
end;
 
多人接受答案了。
 
后退
顶部