Luogu P6394 樱花,还有你题解

原题链接:樱花,还有你 

Solution


Subtask1


  •  这是一个送分的:总和都不到n,无论怎么收集,花瓣数肯定不到n,输出impossible 即可,5分。
  •  因为此题要取模,可能最后答案正好为10086001倍数而为0,但此时应该输出0,而不是impossible !

Subtask2


  • 直接暴搜,20分。

Subtask3


  • 那么,暴搜为什么时间多呢?

    因为一些重复的被算了很多次!例如在第3棵树下收集到5朵,而第4棵树下没有收集与在第4朵树下收集到5朵,除了答案需要再加1外,第5棵树往后是一样的搜法。

  • 考虑优化(记忆化)

    dp[i][j] 表示在第i棵树下,已经收集到j朵花的方案数(取模后的值)

    设k为(0≤k≤min(j,ai)),表示已经收集到的k朵樱花🌸

    那么转移方程就很简单了:dp[i][j]=∑dp[i1][jk] 记得取模

  • 时间复杂度 Ο(n3)

Subtask4


  •  发现i,j无法省略,考虑能否把枚举k,转移这个循环优化,发现求的是一个像前面和的一个东西,想到了二维线段树前缀和优化
  • 但是,此题只有64MB,MLE,考虑优化空间
  • 发现每一个dp[i][j]只与dp[i1][...]有关,考虑滚动数组优化

Code

 

复制代码
//From:201929
#include<bits/stdc++.h>
#define L long long
const int mod=10086001;
using namespace std;
int a[5005],sum[5005];
int dp[5005];
int main()
{
    int n,k,summ=0,ans=0;
    scanf("%d%d",&n,&k);
    for(int i=1;i<=k;i++) scanf("%d",&a[i]),summ+=a[i];
    if(summ<n) return printf("impossible"),0;
    sum[0]=1;
    for(int i=1;i<=a[1];i++) sum[i]=sum[i-1]+1;
    for(int i=a[1]+1;i<=n;i++) sum[i]=sum[i-1];
    if(a[1]>=n) ans++;
    for(int i=2;i<=k;i++)
    {
        for(int j=0;j<=n;j++)
        {
            if(j>a[i]) dp[j]=(sum[j]-sum[j-a[i]-1]+mod)%mod;
            else dp[j]=sum[j]%mod;
        }
        sum[0]=dp[0];
        for(int j=1;j<=n;j++) sum[j]=(sum[j-1]+dp[j])%mod;
        ans=(ans+dp[n])%mod;
    }
    printf("%d",ans);
    return 0;
}
复制代码

 

 

 

 


后记:

  • 这是本蒟蒻的第一篇文章,如有写错的、写得不好的敬请提出。

 

posted @   201929  阅读(31)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
点击右上角即可分享
微信分享提示