bzoj1025: [SCOI2009]游戏

传送门

首先根据置换的知识,

每一个置换都可以表示成若干不想交的循环的乘积

所有循环的规模A1+A2+……AK=n(显然)

然后设最小公倍数为T

则T可以写成a1^m1*a2^m2*a3^m3......的形式

所以A1*A2*A3*......=a1^m1*a2^m2*a3^m3......

当sigma(a[i])最小时显然有A1=a1^m1,A2=a2^m2,A3=a3^m3

当sigma(a[i])=n是显然成立

当sigma(a[i])<n是我们可以加1使得他成立

于是我们可以背包解决

f[i][j]表示前i个指数凑出j的方案数

答案显然是sigma(f[tot][j]) tot为1000以内质数个数。

var
  f:array [0..205,0..1005] of int64;
  a:array [0..205] of longint;
  ans:int64;
  n,i,j,k,ff:longint;
begin
  read(n);
  for i:=2 to n do begin
    ff:=0;
    for j:=2 to trunc(sqrt(i)) do
      if (i mod j=0) then begin ff:=1; break; end;
    if (ff=0) then begin inc(a[0]); a[a[0]]:=i; end;
  end;
  f[0,0]:=1;
  for i:=1 to a[0] do
    for j:=0 to n do begin
      f[i,j]:=f[i,j]+f[i-1,j];
      k:=a[i];
      while (k<=j) do begin f[i,j]:=f[i,j]+f[i-1,j-k]; k:=k*a[i]; end;
    end;
  ans:=0;
  for i:=0 to n do ans:=ans+f[a[0],i];
  write(ans);
end.




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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值