相邻染色问题java_浅析一类要求相邻不同的环上染色问题

经典

我们先来解决最经典的圆环染色问题。

一个环上有\(n\)个点,每个点染为\(m\)种颜色之一,要求相邻两点颜色不同。求可行的方案数。

dbd0b31d207cee5bf602aa9ce1aaa227.png

——《彩色圆环(circle)》命题报告,吴佳俊

那么,设\(f[i][0/1]\)表示当前正在决定第\(i\)位的颜色,且要求该颜色是否(\(0/1\))与第\(1\)位颜色相同。

对于\(f[i][1]\)没啥好决定的,第\(i\)位必须与第\(1\)位相同,所以系数是\(1\)。

对于\(f[i][0]\)分两种情况,一种前接\(f[i-1][1]\),这时第\(i-1\)位颜色与第\(1\)位颜色相同,有\((m-1)\)种颜色供第\(i\)位选择。一种是前接\(f[i-1][0]\),第\(i-1\)位与第\(i\)位不同了,第\(i\)位不能与其中任一相同,只有\((m-2)\)种可以选。

\[\begin{aligned}

f[i][0] &= (m-2) f[i-1][0] + (m-1) f[i-1][1] \\

f[i][1] &= f[i-1][0]

\end{aligned}

\]

初始状态很重要,保险的定义应该从\(2\)开始,但是根据意义从\(1\)开始也无妨。

#include

#include

#include

using namespace std;

typedef long long ll;

const ll MOD=998244353;

const ll MXN=1E7+5;

ll f[MXN][2];

int main(){

ll N,M;scanf("%lld%lld",&N,&M);

f[1][0]=0,f[1][1]=M;

for(ll i=2;i<=N;i++){

f[i][0]=((M-1)*f[i-1][1]+(M-2)*f[i-1][0])%MOD;

f[i][1]=f[i-1][0]%MOD;

}

cout<

return 0;

}

上面这个dp其实还可以更优ÿ

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值