ABC178 D - Redistribution

15 篇文章 0 订阅

ABC178 D - Redistribution

求将 S ( 1 ≤ N ≤ 2000 ) S(1 \le N \le 2000) S(1N2000)拆分为一个序列,且序列中所有值均 ≥ 3 \ge 3 3的方案数。 (   m o d   1 e 9 + 7 ) (~mod~1e9+7) ( mod 1e9+7)

Solution

计数DP?
状态:设 f [ i ] f[i] f[i]表示第 i i i个数的方案数。
转移: f [ i ] = ∑ j = 0 i − 3 f [ j ] f[i]=\sum _{j=0} ^{i-3} f[j] f[i]=j=0i3f[j],表示结尾数为 i − j i-j ij的方案数。
初始化: f [ 3 ] = 1 f[3]=1 f[3]=1
这样我们就得到了一个 O ( N 2 ) O(N^2) O(N2)的DP。

Extra

这道题可以 O ( N ) O(N) O(N)解决。
转移改为: f [ i ] = f [ i − 1 ] + f [ i − 3 ] f[i]=f[i-1]+f[i-3] f[i]=f[i1]+f[i3]即可, f [ i − 1 ] = ∑ j = 0 i − 4 f [ j ] f[i-1]=\sum _{j=0} ^{i-4} f[j] f[i1]=j=0i4f[j],这道题的DP本质是一个前缀和,自然可以优化为线性。

Code

#include <bits/stdc++.h>
#define fi first
#define se second
#define mp make_pair

using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
const double eps = 1e-8;
const int NINF = 0xc0c0c0c0;
const int INF = 0x3f3f3f3f;
const ll mod  = 1e9 + 7;
const ll N = 3e3 + 5;

ll f[N],n;

int main(){
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cin>>n;
    f[3]=1;
   	for(int i=4;i<=n;i++) f[i]=(f[i-1]+f[i-3])%mod;
    cout<<f[n];
    return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值