AtCoder Beginner Contest 179 D题解

题目链接

Problem Statement

There are N cells arranged in a row, numbered 1,2,…,N from left to right.

Tak lives in these cells and is currently on Cell 1. He is trying to reach Cell N by using the procedure described below.

You are given an integer K that is less than or equal to 10, and K non-intersecting segments [L1,R1],[L2,R2],……,[LK,RK]. Let S be the union of these K segments. Here, the segment [l,r] denotes the set consisting of all integers i that satisfy l≤i≤r.

When you are on Cell i, pick an integer d from S and move to Cell i+d.You cannot move out of the cells.

To help Tak, find the number of ways to go to Cell N, modulo 998244353.

Constraints

2≤N≤2×105
1≤K≤min(N,10)
1≤Li≤Ri≤N
[Li,Ri]and [Lj,Rj] do not intersect (i≠j)
All values in input are integers.

思路

设dp[i]为到达i的方案数,则可以得出dp[i]=dp[i-r]+dp[i-r+1]+……+dp[i-l]。(因为可走的距离区间为l到r,所以在i-r到i-l范围内的位置都符合当前要求)
对于这样的前缀和数组,再使用sum记录结果便可以快速得出结论。

代码

#include<map>
#include<set>
#include<stack>
#include<queue>
#include<string>
#include<math.h>
#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
#define pb push_back
using namespace std;
const int mod=998244353;
const int maxn=1e6+5;
typedef long long ll;
const int inf=0x3f3f3f3f;
const int minn=0xc0c0c0c0;
ll k,n,l[maxn],r[maxn],dp[maxn],sum[maxn];
int main()
{
    scanf("%lld%lld",&n,&k);
	for(int i=1;i<=k;i++)
		scanf("%lld%lld",&l[i],&r[i]);
	sum[1]=1;//dp[i]的前缀和 
	for(int i=2;i<=n;i++)
	{
		for(int j=1;j<=k;j++)
			dp[i]=(dp[i]+sum[max((ll)0,i-l[j])]-sum[max((ll)0,i-r[j]-1)])%mod;//走到i的方案数,注意防止越界情况
		sum[i]=(sum[i-1]+dp[i])%mod;
	}
	printf("%lld\n",(dp[n]+mod)%mod);
    return 0;
}
©️2020 CSDN 皮肤主题: 深蓝海洋 设计师:CSDN官方博客 返回首页