用m种颜色着色圆的n个扇形的方法总数

题目: 将圆分成 n n 个扇形,用 m m 种不同颜色染色,并且相邻的扇形不同色,问有多少种着色方法。

分析: 假设将圆分成 n n 个扇形符合题意的着色方法有 An A n 种。
对第一个扇形着色有 m m 种,第二个扇形有 (m1) ( m − 1 ) 种,第三个扇形有 (m1) ( m − 1 ) … … n n 个扇形有 (m1) ( m − 1 ) 种,但是这样着色会存在第 n n 个扇形和第一个扇形同颜色的情况,我们应该减去这样的情况。若第 n n 个扇形和第一个扇形同色,把这两个扇形合成一块,这就相当于 (n1) ( n − 1 ) 个扇形用 m m 种颜色着色问题,它的解是 An1 A n − 1 。由上可得出递推公式 An=m(m1)n1An1 A n = m ∗ ( m − 1 ) n − 1 − A n − 1 ,对这个式子移项化简得到 An(m1)n=(An1(m1)n1) A n − ( m − 1 ) n = − ( A n − 1 − ( m − 1 ) n − 1 ) ,由此得到 An(m1)n A n − ( m − 1 ) n 是公比为 1 − 1 的等比数列。
n=1 n = 1 A1=m A 1 = m
n=2 n = 2 A2=m(m1) A 2 = m ( m − 1 )
n3 n ≥ 3 An(m1)n=[A2(m1)2](1)n2 A n − ( m − 1 ) n = [ A 2 − ( m − 1 ) 2 ] ∗ ( − 1 ) n − 2 ,化简得到 An=(m1)n+(m1)(1)n A n = ( m − 1 ) n + ( m − 1 ) ∗ ( − 1 ) n

当然要是直接写算法求解的话,得到上面的递推公式就可以了,不需要解出后面的通项公式。

public int colorCount(int n, int m) {
    if (n <= 0)
        return 0;
    if (n == 1)
        return m;
    int[] ans = new int[n + 1];
    ans[1] = m;
    ans[2] = m * (m - 1);
    for (int i = 3; i <= n; i++) {
        ans[i] = (int) (m * Math.pow(m - 1, i - 1) - ans[i - 1]);
    }
    return ans[n];
}

你可能感兴趣的:(算法,数学)