![在这里插入图片描述]()
状态表示
- f[I][j]: 考虑到第i 并且收益为j 的方案数
- 收益是指: 移动后比移动前不同的数是多少
- 收益可以为负数,下标整体偏移2000 // 最大情况就是2000
- 初使化f【0】【0】=1
- 状态转移
* 当a[I]==a[I+1] ,考虑第i个字符 k 个字符都可以,收益不变
* 其他情况 :f[i][j] ,是有哪些状态转移过来的,首先 考虑第i个字符时,代价可以+1(填a[i+1]) 代价可以-1(填a[i]),代价可以不变,填除了a[i],a[i+1]的情况
代码
#include <iostream>
using namespace std;
#define SIS std::ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
#define endl '\n'
using ll = long long;
const int MAXN = 2005;
const int MOD = 998244353;
ll dp[MAXN][MAXN<<1],h[MAXN];
int main()
{
SIS;
int n,k;
cin >> n >> k;
for(int i=1;i<=n;i++) cin >> h[i];
if(k==1)
{
cout << 0 << endl;
return 0;
}
dp[0][2000]=1;
for(int i=1;i<=n;i++)
for(int j=1;j<MAXN<<1;j++)
if(h[i]==h[i%n+1]) dp[i][j]=(dp[i-1][j]*k)%MOD;
else dp[i][j]=(dp[i-1][j-1]+dp[i-1][j+1]+dp[i-1][j]*(k-2))%MOD;
ll ans=0;
for(int i=1;i<=n;i++)
ans=(ans+dp[n][2000+i])%MOD;
cout << ans << endl;
return 0;
}