• P6394 樱花,还有你


    题目链接

    Solution

    最暴力的 dp:设 (f_{i,j}) 表示到第 (i) 棵树下恰好摘取 (j) 朵樱花的方案数。转移方程如下:

    [f_{i,j}=sum_{k=1}^j f_{i-1,k} ]

    特别注意的是,需要满足 (s_i ≥ j - k)

    这样就得到了一个 T 飞的程序。接下来又又又是前缀和优化...注意一下边界,既有上界又有下界。

    优化完之后,你又会发现数组开不下了,因此还需要滚动数组。

    然后这题就做完了。

    Code

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #define LL long long
    using namespace std;
    
    const int N = 233333;
    const long long mod = 10086001;
    LL n, k, sum = 0, ans = 0, s[N], g[N], f[2][N];
    
    int main()
    {
        scanf("%lld%lld", &n, &k);
        for(int i = 1; i <= k; i++) scanf("%lld", &s[i]), sum += s[i];
        if(sum < n) { printf("impossible"); return 0; }
        f[0][0] = f[1][0] = 1;
        for(int i = 1; i <= k; i++)
        {
            f[i & 1][0] = 1;
            for(int j = 1; j <= n; j++) f[i & 1][j] = 0;
            for(int j = 0; j <= n; j++) g[j] = (g[j - 1] + f[(i - 1) & 1][j] + mod) % mod;
            for(int j = 1; j <= n; j++)
            {
                if(j - s[i] - 1 >= 0) f[i & 1][j] = (f[i & 1][j] + g[j] - g[j - s[i] - 1] + mod) % mod;
                else f[i & 1][j] = (f[i & 1][j] + g[j] + mod) % mod;
            }
            ans = (ans + f[i & 1][n] + mod) % mod;
        }
        printf("%lld", ans % mod);
        return 0;
    }
    
  • 相关阅读:
    平方十位数
    随意组合
    显示二叉树
    四阶幻方
    方格填数
    数字排列
    青蛙跳N阶(变态跳)
    Mysql可重复读、避免幻读原理
    动态规划典型例题--连续子数组的最大和
    行列有序的二维数组查找
  • 原文地址:https://www.cnblogs.com/Andy-park/p/13834351.html
Copyright © 2020-2023  润新知