其他分享
首页 > 其他分享> > AcWing 1307. 牡牛和牝牛

AcWing 1307. 牡牛和牝牛

作者:互联网

题目传送门

一、算法分析

通过s[i]记录f[0] + ... + f[i]的前缀和可以优化到\(O(n)\)

二、朴素版本

#include <bits/stdc++.h>
using namespace std;

const int N = 100010, mod = 5000011;

int n, k;
int f[N];
// PASS 8/12 其它的TLE,需要优化
int main() {
    cin >> n >> k;
    f[0] = 1; //表示没有公牛
    for (int i = 1; i <= n; i++) {
        if (i - k - 1 < 0)
            f[i] = 1; //如果是前几个,不足k个的时候,其实每个位置,
        //都是可能做为公牛位的,但是,只有一种可能,就是它是公牛位,它前面都不是公牛位
        else {
            //当位置超过了 i-k-1(看图),如果当前位是公牛位,那么前一个公牛位就需要枚举每个可能的位置了
            for (int j = 0; j <= i - k - 1; j++) f[i] = (f[i] + f[j]) % mod;
        }
    }

    int res = 0;
    for (int i = 0; i <= n; i++) res = (res + f[i]) % mod;

    printf("%d\n", res);
    return 0;
}

三、递推版本I

#include <bits/stdc++.h>
using namespace std;

const int N = 100010, mod = 5000011;

int n, k;
int f[N], s[N];

int main() {
    cin >> n >> k;

    f[0] = s[0] = 1;
    for (int i = 1; i <= n; i++) {
        if (i - k - 1 > 0)
            f[i] = s[i - k - 1]; //利用前缀和优化
        else
            f[i] = 1;

        s[i] = (s[i - 1] + f[i]) % mod; //维护前缀和
    }
    cout << s[n] << endl;
    return 0;
}

四、递推优化版本

#include <bits/stdc++.h>
using namespace std;

const int N = 100010, mod = 5000011;

int n, k;
int f[N], s[N];

int main() {
    cin >> n >> k;

    f[0] = s[0] = 1;
    for (int i = 1; i <= n; i++) {
        f[i] = s[max(i - k - 1, 0)];    //利用前缀和优化
        s[i] = (s[i - 1] + f[i]) % mod; //维护前缀和
    }
    cout << s[n] << endl;
    return 0;
}

标签:1307,const,int,namespace,牝牛,include,100010,AcWing,mod
来源: https://www.cnblogs.com/littlehb/p/16348859.html