☆逆序对 动态规划+高精度

来源:互联网 发布:linux 运行sh脚本 编辑:程序博客网 时间:2024/05/20 18:52
     From KQZXCMH逆序对    

 

 

 

 

背景 Background

 

 

柯桥中学60周年校庆欢乐赛第3题

 

 

 

 

 

 

 

描述 Description

 

 

  问题概括:n个元素的排序一共有n!个,询问排列中逆序对个数为m个的排列有多少个。

 

 

 

 

 

 

 

输入格式 Input Format

 

 

输入文件仅一行有两个正整数n,m

 

 

 

 

 

 

 

输出格式 Output Format

 

 

仅有一行,即满足要求的排列的个数

 

 

 

 

 

 

 

样例输入 Sample Input [复制数据]

 

 

 

 

 

 

 

 

 

样例输出 Sample Output [复制数据]

 

 

 

 

 

 

 

 

 

时间限制 Time Limitation

 

 

1s

 

 

 

 

 

 

 

注释 Hint

 

 

对于20%的数据,n<=10
对于40%的数据,n<=20
对于100%的数据,1<=n<=50  m<=(n-1)*n/2

 

Problem 3 逆序对 pair
考察算法 动态规划+高精度
题目大意 求1~N 的排列中有多少个排列的逆序对个数刚好为 M个。
主要算法 本题的动态规划算法很容易想到。F[i,j]表示 1~i 形成的排列中恰好有 j对
逆序对的个数。那么动态规划就可以用插入法来做,将 i+1 插入到i+1 个位置
中可以增加0~i个逆序对。
i-1
转移方程为 f[i, j]= f[i-1, j -k](j >=k)

k=0
因为 n<=50,结果就要用高精度来做了。

 

const md=1000000;type arr=array[0..100] of longint;var f:array[0..50,0..500] of arr;n,m,i,j,k,sum:longint;procedure jia(var a,b:arr);var i,j,len:longint;begin if a[0]>b[0] then len:=a[0] else len:=b[0]; for i:=1 to len do  begin   a[i]:=a[i]+b[i];   a[i+1]:=a[i+1]+a[i] div md;   a[i]:=a[i] mod md;  end; if a[len+1]>0 then inc(len); a[0]:=len;end;procedure print(a:arr);var i:longint;begin write(a[a[0]]); for i:=a[0]-1 downto 1 do  begin   if a[i]<100000 then write(0);   if a[i]<10000 then write(0);   if a[i]<1000 then write(0);   if a[i]<100 then write(0);   if a[i]<10 then write(0);   write(a[i]);  end;end;begin {assign(input,'pair.in'); assign(output,'pair.out'); reset(input); rewrite(output);} readln(n,m); f[0,0][0]:=1; f[0,0][1]:=1; for i:=1 to n do  for j:=0 to m do   for k:=0 to i-1 do    if k<=j then    jia(f[i,j],f[i-1,j-k]); print(f[n,m]); {close(input); close(output);} end.


 

 

原创粉丝点击