NOIP2008T3 传球游戏

 

动态规划

//为了方便边界跨越,人的数组下标从0开始。a[i,j]编号为i的人表示j次传球以后有多少种方式获得球。
var n,m,i,j:longint;
    a:array[0..30,0..30] of longint;
begin
    assign(input,'ballg.in'); reset(input);
    assign(output,'ballg.out'); rewrite(output);
    readln(n,m);
    for i:=1 to n-1 do a[i,0]:=0;
    a[0,0]:=1;//球还没有开始传,在0号,即小蛮手中
    for j:=1 to m do//表示第几次传球
        for i:=0 to n do
            a[i,j]:=a[(i+1) mod n,j-1]+a[(i-1+n) mod n,j-1];//每个人只能从上一个或下一个人手中拿到球
    writeln(a[0][m]);
    close(input); close(output);
end.


DFS(WA40)

var n,m:longint;
    ans:int64;
procedure find(i,j:integer);
begin
  if (i=m)  then
    begin
       if j=1 then
       ans:=ans+1;
    exit;
  end;
  find(i+1,j mod n+1);
  if j=1  then
  find(i+1,n)
  else find(i+1,j-1);
end;
begin
  readln(n,m);
  if (n mod 2=0) and (m mod 2=1) then
    begin
      writeln('0');
      halt;
    end;
  find(0,1);
  writeln(ans);
end.

 

 

var n,m,c,i:longint;
    ans:int64;
    next,pre:array[1..1000] of longint;
procedure DFS(j:integer);
begin
  if(c=m) then
  begin
      if j=1 then ans:=ans+1;
      exit;
  end;
  inc(c); DFS(next[j]); dec(c);
  inc(c); DFS(pre[j]); dec(c);
end;
begin
    readln(n,m);
    if (n mod 2=0) and (m mod 2=1) then begin writeln('0'); halt; end;
    for i:=1 to n-1 do next[i]:=i+1; next[n]:=1;
    for i:=2 to n do pre[i]:=i-1; pre[1]:=n;
    c:=0;
    DFS(1);
    writeln(ans);
end.

 

 

var n,m,i:longint;
    ans:int64;
    next,pre:array[1..1000] of longint;
procedure DFS(i,j:integer);
begin
  if(i=m) then
  begin
      if j=1 then ans:=ans+1;
      exit;
  end;
  DFS(i+1,next[j]);
  DFS(i+1,pre[j]);
end;
begin
    readln(n,m);
    if (n mod 2=0) and (m mod 2=1) then begin writeln('0'); halt; end;
    for i:=1 to n-1 do next[i]:=i+1; next[n]:=1;
    for i:=2 to n do pre[i]:=i-1; pre[1]:=n;
    DFS(0,1);
    writeln(ans);
end.

 

 

posted @ 2013-10-26 16:11  qilinart  阅读(227)  评论(0)    收藏  举报