逆序对 解题报告

49 篇文章 0 订阅
35 篇文章 0 订阅
 

时间限制: 10000ms 内存限制: 131072kB

描述 问题概括: n 个元素的排序一共有 n! 个,询问排列中逆序对个数为 m 个的排列有多少个。 输入 输入文件仅一行有两个正整数 n , m 输出 仅有一行 , 即满足要求的排列的个数

样例输入 3 2

样例输出 2提示

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

思路:动态规划

f[i,j] 表示1-i形成的排列恰好有j个逆序对的个数

那么

f[i,j]:=sum(f[i-1,j-k]) (0<=k<=i-1,k<=j)

n<=50所以还要用高精度。

来源:tyvj 柯桥中学60周年欢乐赛

提交地址:http://hzoi.openjudge.cn/codewaysky/1016/

ac程序:

type arr=array[0..100] of longint;
var f:array[0..50,0..1250] of arr;
{f:array[0..50,0..50] of longint;}
n,m,i,j,k:longint;
procedure jia(var a,b:arr);
var i,j,len:longint;
begin
 len:=a[0];
 if len<b[0] then 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 10000;
   a[i]:=a[i] mod 10000;
  end;
 if a[len+1]>0 then inc(len);
 a[0]:=len;
end;
procedure print;
var i,len:longint;
begin
  len:=f[n,m][0];
  write(f[n,m][len]);
 for i:=len-1 downto 1 do
  begin
   if f[n,m][i]<1000 then write(0);
   if f[n,m][i]<100 then write(0);
   if f[n,m][i]<10 then write(0);
   write(f[n,m][i]);
  end;
end;
begin
 readln(n,m);
 f[0,0][0]:=1;
 for i:=1 to n do
  for j:=1 to m do
   begin
   f[i,0][0]:=1; f[i,0][1]:=1;
   f[i,j][0]:=1;
   for k:=0 to i-1 do
    if j>=k then
     jia(f[i,j],f[i-1,j-k]);
   end;
 print;
 {f[1,0]:=1;
 for i:=1 to n do
  begin
  f[i,0]:=1;
  for j:=1 to m do
   for k:=0 to i-1 do
    if j>=k then
     f[i,j]:=f[i,j]+f[i-1,j-k];
  end;}
 {writeln(f[n,m]);}
end.



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值