设 fi:1∼if_{i}:1\sim ifi:1∼i 能否分成若干个首尾相同的区间
则有 fi=ORj<i(fj−1∧aj=ai)f_{i}=\text{OR}_{j<i}(f_{j-1}\wedge a_j=a_i)fi=ORj<i(fj−1∧aj=ai)。
这是最原始的暴力 dpdpdp,时间 O(n2m)O(n^2m)O(n2m)。
事实上,这个过程中 iii 只有选那些 fj−1=1f_{j-1}=1fj−1=1 的 aja_jaj 构成的颜色集合才能使得 fi=1f_i=1fi=1。
因此有效状态只有不同颜色集合大小和上个位置的 fff 值。
我们考虑设计只跟有效状态挂钩的 dpdpdp。
设 dpi,j,k:dp_{i,j,k}:dpi,j,k: 处理完了 [1,i)[1,i)[1,i) 的信息,有 jjj 个满足的不同颜色,且上一位( fi−1f_{i-1}fi−1 )是否为 111。
有四种转移情况:
-
dpi+1,j,1←dpi,j,1∗jdp_{i+1,j,1}\leftarrow dp_{i,j,1}*jdpi+1,j,1←dpi,j,1∗j
虽然 fi−1=1f_{i-1}=1fi−1=1,但 aia_iai 选取的颜色是前面 jjj 个合法位置上的任一颜色,颜色集合并未发生改变,同时有 fi=1f_i=1fi=1。
-
dpi+1,j,1←dpi,j,0∗jdp_{i+1,j,1}\leftarrow dp_{i,j,0}*jdpi+1,j,1←dpi,j,0∗j
虽然 fi−1=0,if_{i-1}=0,ifi−1=0,i 不可能产生贡献。但反正前面至少有 jjj 个位置满足 fk−1=1f_{k-1}=1fk−1=1 且 aka_kak 互不相同。
iii 仍然可以让 aia_iai 成为这其中任一颜色,也会使得 fi=1f_i=1fi=1。
-
dpi+1,j,0←(m−j)dpi,j,0dp_{i+1,j,0}\leftarrow (m-j)dp_{i,j,0}dpi+1,j,0←(m−j)dpi,j,0
fi=0f_i=0fi=0 说明 aia_iai 没有和前面的 jjj 个位置有关联,颜色是剩下的 m−jm-jm−j 种,合法颜色集合大小 jjj 也不会增。
-
dpi+1,j+1,0←(m−j)dpi,j,1dp_{i+1,j+1,0}\leftarrow (m-j)dp_{i,j,1}dpi+1,j+1,0←(m−j)dpi,j,1
fi=0f_i=0fi=0 但 fi−1=1f_{i-1}=1fi−1=1 这意味着,aia_iai 的颜色与前面合法的 jjj 个位置不同,但 iii 此时进入候选位置,合法颜色集合大小会 +1+1+1。
#include <bits/stdc++.h>
using namespace std;
#define int long long
#define mod 1000000007
#define maxn 3005
int n, m;
int f[maxn][maxn][2];signed main() {scanf( "%lld %lld", &n, &m );f[0][0][0] = f[0][0][1] = 1;for( int i = 0;i < n;i ++ )for( int j = 0;j <= i;j ++ ) {( f[i + 1][j][1] += ( f[i][j][0] + f[i][j][1] ) % mod * j ) %= mod;( f[i + 1][j + 1][0] += f[i][j][1] * ( m - j ) ) %= mod;( f[i + 1][j][0] += f[i][j][0] * ( m - j ) ) %= mod;}int ans = 0;for( int i = 0;i <= n;i ++ )( ans += f[n][i][1] ) %= mod;printf( "%lld\n", ans );;return 0;
}