2020 NOI Online 入门组]跑步

[2020 NOI Online 入门组]跑步(民间数据)

思路:

这题其实就是一个背包的模板,但是他也有一个难点:他的数据太大了……

测试点编号 n ≤ n \leq n测试点编号 n ≤ n \leq n
1 1 1 5 5 5 6 6 6 2000 2000 2000
2 2 2 10 10 10 7 7 7 5000 5000 5000
3 3 3 50 50 50 8 8 8 20000 20000 20000
4 4 4 100 100 100 9 9 9 50000 50000 50000
5 5 5 500 500 500 10 10 10 100000 100000 100000

我们的背包DP在测试点8的时候还能应付,但是到了测试点9和测试点10的时候就会超时

            f[j] = (f[j - i] + f[j]) % p;

在这里插入图片描述

然后我们就 没办法了,等S吧还有一个办法,他就是……

整数的无序分拆!

整♪数♪的♪无♪序♪分♪拆,我♪的♪救♪星♪

首先我们先定义状态:

f ( n , k ) f(n,k) f(n,k) n n n拆成 k k k个正整数部分有 f ( n , k ) f(n,k) f(n,k)种方案( k k k由小到大排列)

f ( n , k ) f(n,k) f(n,k)根据最后一部分是否大于1,分成两种情况

f ( n , k ) = { f ( n − 1 , k − 1 ) A k = 1 f ( n − k , k ) A k > 1 f(n,k)=\begin{cases}f(n-1,k-1) \quad \quad A_k = 1 \\f(n - k, k) \quad \quad \quad A_k > 1\end{cases} f(n,k)={f(n1,k1)Ak=1f(nk,k)Ak>1

∴ f ( n , k ) = f ( n − 1 , k − 1 ) + f ( n − k , k ) ∴f(n,k)=f(n-1,k-1)+f(n-k,k) f(n,k)=f(n1,k1)+f(nk,k)

我们接着将我们敬爱的小H的跑步的速度x分为两类来做

  1. x ≤ n x \leq \sqrt n xn

    f [ n ] = f [ n − x ] f[n]=f[n-x] f[n]=f[nx]
    那么我们 O ( n n ) O(n\sqrt n) O(nn )

  2. x > n x > \sqrt n x>n

    g ( n , k ) = g ( n − 1 , k − 1 ) + g ( n − k , k ) k ≤ n g(n,k) = g(n-1,k-1)+g(n-k,k) \quad k \leq \sqrt n g(n,k)=g(n1,k1)+g(nk,k)kn

    那么我们的时间复杂度又是 O ( n n ) O(n\sqrt n) O(nn )我们就不会超时啦啦♪(*)

最终的递推式是这样的:
∑ i = 1 i < = n ( f [ i ] ∗ ∑ k = 1 k < n g ( n − i , k ) ) \sum_{i=1}^{i<=n}(f[i] * \sum_{k=1}^{k< \sqrt n} g(n-i,k)) i=1i<=n(f[i]k=1k<n g(ni,k))


思路到此结束,代码写不来如下

    f[j]=(f[j-i]+f[j])%p;
    g[0][0]=1;
    g[i][1]=1;
    g[i][j]=(g[i-j][j]+g[i-m][j-1])%p;
    ans=(ans+1ll*f[i]*g[n-i][j])%p;

亲测AC~~~

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值