60pts(理论)
一道很有意思的dp
,当然如果你直接开dp[5005][5005][5005]
的话显然MLE,那么我们可以用map
替代(避雷不要使用vector
,因为使用了这个你在状态转移的时候会越界。
dp[i][j][k]
表示考虑前 i 种情况时: 第 i - 1 还剩余 j 个, 第 i 个还剩余 k 个的方案。当前我们一定要把 j 消掉变成 0
之后才能从 dp[i - 1]
转移到 dp[i]
且只能通过三个连续自然数的方式进行 (x , x+1, x+2) (因为如果是3的整数倍的话就在 dp[i - 1]
的内部自我转移完成了)最后我们可以通过在dp[i]
内部自我转移,只能使用 (x,x,x) 的形式。
dp[i][j][k] = (dp[i][j][k] + dp[i][j][k + 3]) % Mod;
dp[i + 1][k - j][a[i + 1] - j] = (dp[i + 1][k - j][a[i + 1] - j] + dp[i][j][k]) % Mod;
这里的第一行就是自我转移的过程( k 不断 +3
)
第二行就是 dp[i]
向 dp[i + 1]
转移的过程。
100pts
其实 100pts
只需要在上述过程稍加改进,注意枚举的边界 \sum cnt = 3 \times n , {\textstyle \sum_{i - 1}^{m - 1}} cnt_i \times cnt_{i - 1} 是 O(n^2) 量级的,不会 TLE
,根据上述dp
注意边界即可