安全序列dp及前缀和

文章讨论了一个关于在给定位置间隔k的情况下,放置桶的动态规划问题。使用前缀和优化了常规的嵌套循环,避免了超时,主要关注了计算以位置i结尾的方案总数dp[i]的方法。
摘要由CSDN通过智能技术生成

在这里插入图片描述
分析:

在这里插入图片描述
就比如说这里有5个位置,间隔k=2,那么就有以下几种情况:
放一个桶:(1)、(2)、(3)、(4)、(5)
放两个桶:(1,4)、(1,5)、(2,5)
放三个桶:三个及以上放不下了。
那么,就有8中方案放桶了。
设置 dp[i] 表示以位置 i 结尾的方案总数。dp[1] = 1, dp[2] = 1,dp[4] = 2, dp[5] = 3…
因为,5-2-1=2>=1(i - k - 1),所以 dp[i] = 1,只用一种方案,因为要放更多的桶,那么我们就需要在左边有位置,如果小于1的话就表示没有位置了。
同时又因为n的范围是1e6,我们外循环遍历n个位置的时候,我们也要让dp[i]的数据变化,如果使用循环嵌套的话,那么就会超时。因此我们在计算和的时候,我们使用前缀和。

注意:

这将运行超时,使用前缀和优化。

	for(int i=1;i<=n;i++){
		dp[i]=0;
		for(int j=max(0,i-k);j<i;j++){
			dp[i]=(dp[i]+dp[j])%p;
		}
	}
	cout<<dp[n]<<"\n";

示例代码:

#include<bits/stdc++.h>
using namespace std;
const int p = 1e9+7,N = 1e6+5;
int dp[N],prefix[N];
int main(){
	ios::sync_with_stdio(false);cin.tie(nullptr);cout.tie(nullptr);
	int n,k;cin>>n>>k;
	
	dp[0]=prefix[0]=1;
	for(int i=1;i<=n;i++){
		if(i-k-1<1)dp[i]=1;
		else dp[i]=prefix[i-k-1];
		prefix[i]=(prefix[i-1]+dp[i])%p;
	}
	cout<<prefix[n]<<'\n';
	return 0;
}
  • 7
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

席万里

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值