首页 > 其他分享 >ABC292G Count Strictly Increasing Sequences [区间DP]

ABC292G Count Strictly Increasing Sequences [区间DP]

时间:2024-10-11 17:00:53浏览次数:1  
标签:Count ... int Strictly 严格 1ll Sequences 递增 mod

Description

你有 \(n\) 个数,每个数长度为 \(m\)。

不过这 \(n\) 个数中,可能有某些位不确定,需要你在每个 ? 位置上 \(0\) 到 \(9\) 之间填一个数。设你填出来的序列是 \(\{S_i\}\)。

请你求出,在所有可能的填数方案中,有多少种满足 \(S_1 < S_2 < \dots < S_n\)?对 \(998244353\) 取模。允许前导零存在。

\(n,m \le 40\)。

Solution

推性质:

我们考虑一个合法的序列长什么样,它的每个数的最高位可能是这样的,111...222...333...444......999,

其中,最高位的数严格递增,即可保证序列严格递增,那如果最高位相等,就要求往后一位(去掉最高位后)严格递增。

设状态:

设 \(f(i,j,l,r)\) 表示,当前考虑了后 \(i\) 位(越靠前的位权越高)(\(i\) 是 \(m\) 这一维的),\([l,r]\) (是 \(n\) 这一维的) 这个区间的数严格递增,且当前填的最大的数是 \(j\),的方案数。

举个例子:\(12345,12356,12378,12390\),\(f(2,1,4,9)\) 就表示 \([1,4]\) 的数,\(45<56<78<90\),且最大的数是 \(\max\{4,5,7,9\}\)。

写转移:

我们枚举一个 \(k\),表示 \([l,k]\) 的数严格递增,\([k+1,r]\) 的数最高位相等,

转移即是:\(f(i,j,l,r)=\sum f(i,j-1,l,k)\times f(i+1,9,k+1,r)\),

含义就是,既然 \([l,k]\) 的数严格递增,于是我们就直接算上它的贡献,然后再保证 \([k+1,r]\) 严格递增,保证的方法就是让它上一位严格递增。

然后 \(j\) 这一维是可以用滚动数组滚掉的。

时间:\(O(n^3m\left|\sum\right|)\),空间:\(O(n^3)\)。

Code

const int N = 40 + 5, mod = 998244353;

int n, m;
string s[N];
int f[N][N][N], g[N][N][N]; // 滚动数组

void Solve(){
	cin >> n >> m;
	for(int i = 1; i <= n; i++){
		cin >> s[i];
		s[i] = " " + s[i];
	}
	for(int i = 1; i <= n; i++) f[m + 1][i][i] = 1; // 边界
	for(int i = m; i >= 1; i--){
		for(int j = 0; j <= 9; j++){
			memcpy(g[i], f[i], sizeof(f[i]));
			for(int len = 1; len <= n; len++){
				for(int l = 1; l + len - 1 <= n; l++){
					int r = l + len - 1;
					bool flag = true;
					for(int k = r; k >= l; k--){
						if(s[k][i] == '?' || s[k][i] == j + '0'){
							if(k == l) break;
							f[i][l][r] = (1ll * f[i][l][r] + 1ll * g[i][l][k - 1] * f[i + 1][k][r] % mod) % mod;
						}else{
							flag = false;
							break;
						}
					} // 个人代码实现,最后需要特判整个区间都相等,不必纠结
					if(flag) f[i][l][r] = (1ll * f[i][l][r] + f[i + 1][l][r]) % mod;
				}
			}
		}
	}
	cout << f[1][1][n] << endl;
}

标签:Count,...,int,Strictly,严格,1ll,Sequences,递增,mod
From: https://www.cnblogs.com/chenwenmo/p/18458878

相关文章

  • LeetCode 1371. Find the Longest Substring Containing Vowels in Even Counts
    原题链接在这里:https://leetcode.com/problems/find-the-longest-substring-containing-vowels-in-even-counts/description/题目:Giventhestring s,returnthesizeofthelongestsubstringcontainingeachvowelanevennumberoftimes.Thatis,'a','e&......
  • divide by zero encountered in log10 my_vmin=np.log10(data['PValue'].min())
     sm=plt.cm.ScalarMappable(cmap='viridis',norm=plt.Normalize(vmin=np.log10(data['PValue'].min()),vmax=np.log10(data['PValue'].max()))) C:\Python310\lib\site-packages\pandas\core\arraylike.py:397:RuntimeWarning:d......
  • Solution - Atcoder ARC116C Multiple Sequences
    一个\(\mathcal{O}(m^{\frac{3}{4}}\logm)\)做法。令\(a_0=1\)。对于倍数问题,考虑类似差分的思想,定义\(b_i=\frac{a_i}{a_{i-1}}(1\lei\len)\),那么合法的\(a\)和\(b\)是双射的,就只需要考虑对\(b\)计数了。考虑到因为有\(\prod\limits_{i=1}^nb_i\lem\)......
  • openzeppelin/contracts/utils/Counters.sol" not found
    运行以下//SPDX-License-Identifier:MITpragmasolidity0.7.5;import{Counters}from"@openzeppelin/contracts/utils/Counters.sol";contractMyTokenisERC721,Pausable,Ownable{usingCountersforCounters.Counter;Counters.Cou......
  • 【VBA】シート数を取得する【Sheets.Countで取得できます】
    参考元:【VBA】シート数を取得する【Sheets.Countで取得できます】https://daitaideit.com/vba-sheet-count/「Sheets.Count」でシート数を取得SubTEST1()'シート数を取得Debug.PrintSheets.CountEndSubシート数を取得する場面シート数を取得できれば、次......
  • #1118 - Row size too large. The maximum row size for the used table type, not co
    这个问题表示在MySQL中,表的一行数据大小超过了最大限制65535字节。这通常是因为表中的某些字段过长导致的。下面是一些解决方法:调整字段类型:将一些较大的字段改为TEXT或BLOB类型。这些类型的存储方式不同于普通字段,可以避免占用过多的行内空间。拆分字段:如果某个字段包含多......
  • ABC221G Jumping Sequences 题解
    JumpingSequences把移动的上下左右改成左上、左下、右上、右下(坐标轴旋转\(45\)°)。则最终目的地是\((A+B,A-B)\)。(以前移动的方式是\((\pmd_i,0),(0,\pmd_i)\)。现在每次移动的方式是\((\pmd_i,\pmd_i)\))则\(x,y\)两维可以分开考虑。目标:从\(d_1\simd_n\)中选......
  • 题解:CF1976D Invertible Bracket Sequences
    可以在cnblog中阅读。题意给一个合法括号序列,问有多少区间\([l,r]\),使得将区间内的每个括号翻转后,括号序列仍合法。分析十分套路地,我们将(看成\(+1\),将)看成\(-1\),则一个括号序列合法的充要条件是转换后的序列满足:前缀和任意位置非负;最后一项为\(0\)。考虑翻转......
  • 题解:CF2009D Satyam and Counting
    比较容易观察的一道题,但是场上不开longlong见祖宗了。由于这题的\(x\)最大值比较小,所以我们可以直接存每个坐标是否有点。有两种三角形符号条件:存在两个点\((x,0),(x,1)\),可以观察到任意的其它点都可以成为第三点。有三个点为\((x,0),(x+1,1),(x+2,0)\)或\((x,1),(x+1......
  • hdu1705 Count the grid
    皮克定理是指一个计算点阵中顶点在格点上的多边形面积公式,该公式可以表示为2S=2a+b-2,其中a表示多边形内部的点数,b表示多边形边界上的点数,s表示多边形的面积。多边形边界上的整数点怎么求呢?当然是gcd啦~~ gcd(x1-x2,y1-y2)就是这条边上整数点的个数。但是仅仅一条边是不准确的......