您的位置:首页 > 其它

【NOIP2012模拟10.26】电影票

2016-09-10 21:36 274 查看
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.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息