【NOIP2012模拟10.26】电影票

Description

笨笨当了很久的道路调度员,笨笨也开始想体验生活,从生活中发现数学问题,锻炼自己思维。最近《变形金刚3》,《哈利波特7》同步放映,明显是决战雌雄,已知王府井中一共有n人买了《变形金刚3》的票,m人买了《哈利波特7》的票,并且n>=m,并且电影院中现在只有两种票,每次只有一个人买,(共有n+m次),这n+m次组成一个排列,为了保证每一个人买票时,《变形金刚3》票房都不少于《哈利波特7》,(n个买《变形金刚3》的人之间没区别,m个买《哈利波特7》的人也没区别),笨笨想着到这样的购票方案有多少种。笨笨想了好久都没想出来,所以笨笨找到了你。

Input

 一行两个数n,m (  0<=m<=n<=5000)

Output

输出方案种数

题解

 用容斥原理做,要用高精度压位。

代码

const
  mo=1000000000;
var
  a,sum:array [-5..5005] of int64;
  m,n:longint;

procedure cheng(k:longint);
var
  i:longint;
  c:int64;
begin
  c:=0;
  for i:=1 to a[0] do
    begin
      a[i]:=a[i]*k+c;
      c:=a[i] div mo;
      a[i]:=a[i] mod mo;
    end;
  if c=0 then exit;
  inc(a[0]);
  a[a[0]]:=c;
  while (a[a[0]]>=mo) do
    begin
      inc(a[0]);
      a[a[0]]:=a[a[0]-1] div mo;
      a[a[0]-1]:=a[a[0]-1] mod mo;
    end;
end;

procedure chu(k:longint);
var
  i:longint;
  c:int64;
begin
  c:=0;
  for i:=a[0] downto 1 do
    begin
      c:=c*mo+a[i];
      a[i]:=c div k;
      c:=c mod k;
    end;
  while (a[a[0]]=0) and (a[0]>1) do
    dec(a[0]);
end;

procedure jian;
var
  i:longint;
begin
  for i:=1 to sum[0] do
    begin
      if sum[i]<a[i] then
        begin
          dec(sum[i+1]);
          sum[i]:=sum[i]+mo;
        end;
      sum[i]:=sum[i]-a[i];
    end;
  while (sum[sum[0]]=0) and (sum[0]>1) do
    dec(sum[0]);
end;

procedure fd;
begin
  if m<n then begin
                writeln('0'); halt;
              end;
  if n=0 then begin
                writeln('1'); halt;
              end;
end;

procedure trya;
var
  i:longint;
begin
  fillchar(a,sizeof(a),0);
  a[0]:=1; a[1]:=1;
  for i:=1 to n-1 do
    begin
      cheng(m+n-i+1);
      chu(i);
    end;
end;

procedure trysum;
var
  i:longint;
begin
  a[0]:=1; a[1]:=1;
  for i:=1 to n do
    begin
      cheng(m+n-i+1);
      chu(i);
    end;
  sum:=a;
end;

procedure main;
begin
  fd;
  trysum;
  trya;
  jian;
end;

procedure print;
var
  i,l:longint;
  ss:string;
begin
  write(sum[sum[0]]);
  for i:=sum[0]-1 downto 1 do
    begin
      str(sum[i],ss);
      l:=length(ss);
      while l<9 do
        begin
          write('0');
          inc(l);
        end;
      write(ss);
    end;
end;

begin
  readln(m,n);
  main;
  print;
end.

posted @ 2016-09-10 21:37  猪都哭了  阅读(185)  评论(0编辑  收藏  举报