把博客园图标替换成自己的图标
把博客园图标替换成自己的图标end

【前缀和优化dp】ABC179 D Leaping Tak

题目链接

题目解析

其实是一道水题,但我还是想了好久(指\(40min+\)

首先可以搞一个一般的\(dp\)出来:定义\(f[i]\)表示走到\(i\)的方案数

那么有转移:\(f[i]+=f[i-d],d∈S\)

这个转移的复杂度消耗是巨大的,但是由于\(k\)比较小,而且符合条件的转移对象是连续的,所以可以用前缀和优化。

定义\(s[i]=f[1]+f[2]+...+f[i]\)

于是有:\(f[i]+=s[i-L_j]-s[i-R_j-1]\)

复杂度\(O(nk)\)


►Code View

#include<cstdio>
#include<algorithm>
#include<cmath>
using namespace std;
#define LL long long
#define N 200005
#define DEL 100000
#define INF 0x3f3f3f3f
#define MOD 998244353
int rd()
{
	int x=0,f=1;char c=getchar();
	while(c<'0'||c>'9'){if(c=='-')f=-1; c=getchar();}
	while(c>='0'&&c<='9'){x=(x<<3)+(x<<1)+(c^48); c=getchar();}
	return f*x;
}
int n,k;
LL f[N],s[N];
struct node{
	int l,r;
}seg[15];
int main()
{
	n=rd(),k=rd();
	for(int i=1;i<=k;i++)
		seg[i].l=rd(),seg[i].r=rd();
	f[1]=1,s[1]=1;
	for(int i=2;i<=n;i++)
	{
		for(int j=1;j<=k;j++)
			f[i]=(f[i]+s[max(i-seg[j].l,0)]-s[max(i-seg[j].r-1,0)]+MOD)%MOD;
		s[i]=(s[i-1]+f[i])%MOD;
	}
	printf("%lld\n",f[n]);
	return 0;
}

posted @ 2020-11-15 23:07  Starlight_Glimmer  阅读(151)  评论(0编辑  收藏  举报
浏览器标题切换
浏览器标题切换end