题目
给定两个长度为n的非递减序列 a b
定义 序列c满足
ai <= ci <= bi
0 <= ai <= bi <= 3000
1 <= n <= 3000
求出 序列 c 有多少种可能。
题解思路
定义 f[i][j] 为 前i个数字中以j为结尾的非递减序列 的 总数 。
只需满足前一项的小于等于第 i 项即可 。
f [ i ] [ j ] = f [ i - 1 ] [ 0 ] + f[i-1][1] ------- + f [i-1][ j ]
这样我们再转移的时候定义出一个sum来统计这个和即可 。
最后累加符合情况的所有种数即可。
感觉是dp但是写不出 。 。
AC代码
#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
#include <vector>
#include <algorithm>
#include <map>
#include <string>
using namespace std;
const int INF = 0x3f3f3f3f;
const int mod = 998244353 ;
int a [3010] ;
int b [3010] ;
int dp[3010][3010] ;
int main ()
{
ios::sync_with_stdio(false);
int n ;
long long ans = 0 ;
cin >> n ;
for (int i = 1 ; i <= n ; i++ )
cin >> a[i] ;
for (int i = 1 ; i <= n ; i++ )
cin >> b[i] ;
for (int i = a[1] ; i <= b[1] ; i++ )
dp[1][i] = 1 ;
for (int i = 2 ; i <= n ; i++ )
{
int cnt = 0 ;
for (int j = 0 ; j <= b[i] ; j++ )
{
cnt = ( dp[i-1][j] + cnt )% mod ;
if ( j >= a[i] )
dp[i][j] = cnt ;
}
}
for (int i = a[n] ; i <= b[n] ; i++ )
{
ans = ( dp[n][i] + ans )% mod ;
}
cout << ans << "\n" ;
return 0 ;
}