Luogu P6394 樱花,还有你题解
原题链接:樱花,还有你
Subtask1
- 这是一个送分的:总和都不到
,无论怎么收集,花瓣数肯定不到 ,输出impossible 即可, 分。 - 因为此题要取模,可能最后答案正好为10086001倍数而为
,但此时应该输出 ,而不是impossible !
Subtask2
- 直接暴搜,
分。
Subtask3
- 那么,暴搜为什么时间多呢?
因为一些重复的被算了很多次!例如在第3棵树下收集到5朵,而第4棵树下没有收集与在第4朵树下收集到5朵,除了答案需要再加1外,第5棵树往后是一样的搜法。
- 考虑优化(记忆化)
dp[i][j] 表示在第
设
那么转移方程就很简单了:dp[i][j]=∑dp[i−1][j−k] 记得取模
- 时间复杂度 Ο(n3)
Subtask4
- 发现
无法省略,考虑能否把枚举 ,转移这个循环优化,发现求的是一个像前面和的一个东西,想到了二维线段树前缀和优化 - 但是,此题只有64MB,MLE,考虑优化空间
- 发现每一个
只与 有关,考虑滚动数组优化
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; }
后记:
- 这是本蒟蒻的第一篇文章,如有写错的、写得不好的敬请提出。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!