题解:AT_abc222_d [ABC222D] Between Two Arrays

题目链接

思路

这道题一眼的dp

dp首先要设状态,一个很容易想到的状态就是dp[i]dp[i]表示前ii个数有多少种答案。但是我们会发现:dp[i]dp[i]很难从前面的答案转移过来,因为不知道上一次选的数是否大于a[i]a[i]。于是我们考虑加状态,得到dp[i][j]dp[i][j]表示前ii个数最后一个数j\leq j的答案数。

这次,我们就可以很容易的推出状态转移方程:dp[i][j]=dp[i][j1]+dp[i1][minj,b[i1]]dp[i][j]=dp[i][j-1]+dp[i-1][\min{j,b[i-1]}],因为dp[i][j]dp[i][j]包含了所有dp[i][j1]dp[i][j-1],但dp[i][j]dp[i][j]还比dp[i][j1]dp[i][j-1]多了dp[i1][j]dp[i-1][j]。为了防止j>b[i1]j>b[i-1],要将jjb[i1]b[i-1]取一个最小值。

最后,初始化是dp[0][0]=1dp[0][0]=1,答案是dp[n][b[n]]dp[n][b[n]],感觉不用说了。

代码

上面解释的很清楚了懒得写注释了

#include <iostream>
using namespace std;

const int mod=998244353;

int n;
int a[3010],b[3010];
int dp[3010][3010];

int main()
{
	cin>>n;
	for(int i=1;i<=n;i++)
	{
		cin>>a[i];
	}
	for(int i=1;i<=n;i++)
	{
		cin>>b[i];
	}
	dp[0][0]=1;
	for(int i=1;i<=n;i++)
	{
		for(int j=a[i];j<=b[i];j++)
		{
			dp[i][j]=j>=1?dp[i][j-1]:0;
			dp[i][j]=(dp[i][j]+dp[i-1][min(j,b[i-1])])%mod;
		}
	}
	cout<<dp[n][b[n]];
	return 0;
}
posted @   xlaser  阅读(7)  评论(0编辑  收藏  举报  
相关博文:
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
点击右上角即可分享
微信分享提示