1444. Dyeing Problem
There is a circle, divided into n sectors. All the sectors are colored with some of m colors. The colors of adjacent sectors cannot be the same. Find the total number of plans.
Example
Example 1:
Input:n = 2,m = 3
Output:6
Explanation:One circle is divided into two sectors. There are six kinds of schemes for coloring in three colors: black, red, black and white, white and red, white and black, red and white, and red and black.
Example 2:
Input:n = 3,m = 2
Output:0
Explanation:A circle is divided into 3 sectors and colored with 2 colors. No matter how it is colored, there is no guarantee that the adjacent colors are different.
Notice
Do not consider symmetry.
Since this number may be large, you only need to return the solution number mod 1e9 + 7.
1 \leq n \leq 10^5
1 \leq m \leq 10^5
解法1:DP
dp[i]表示有i个sector的圆能构成的plan总数。那么当i>=4时,dp[i]有2种可能:
1) i-1个sector的圆的第一个sector和最后一个sector同色,此时这i-1个sector所构成的plan总数就是dp[i-2]。注意,根据题目首尾不能同色,所以这种情况就是dp[i - 2],跟dp[i-1]没关系。第i个sector有m-1种可能,因为是往2个同色的sector中间插入。
2) i-1个sector的圆的第一个sector和最后一个sector不同色,此时这i-1个sector所构成的plan总数就是dp[i-2]。第i个sector有m-2种可能,因为是往2个不同色的sector中间插入。
class Solution {
public:
/**
* @param n: the number of sectors
* @param m: the number of colors
* @return: The total number of plans.
*/
int getCount(int n, int m) {
//dp[i] is the total # of plans with a circle with i sectors
vector<int> dp(n + 1, 0);
dp[1] = m;
dp[2] = (long) dp[1] * (m - 1) % 1000000007;
dp[3] = (long) dp[2] * (m - 2) % 1000000007;
for (int i = 4; i <= n; ++i) {
//if the first sector and the last sector are same color
dp[i] = (long) dp[i - 2] * (m - 1) % 1000000007;
//if the first sector and the last sector are not same color
dp[i] += (long) dp[i - 1] * (m - 2) % 1000000007;
dp[i] %= 1000000007;
}
return dp[n];
}
};
解法2:解法1+滚动数组优化
class Solution {
public:
/**
* @param n: the number of sectors
* @param m: the number of colors
* @return: The total number of plans.
*/
int getCount(int n, int m) {
//dp[i] is the total # of plans with a circle with i sectors
vector<int> dp(3, 0);
dp[1] = m;
dp[2] = (long) dp[1] * (m - 1) % 1000000007;
dp[0] = (long) dp[2] * (m - 2) % 1000000007; // 0 = 3 % 3
for (int i = 4; i <= n; ++i) {
//if the first sector and the last sector are same color
dp[i % 3] = (long) dp[(i - 2) % 3] * (m - 1) % 1000000007;
//if the first sector and the last sector are not same color
dp[i % 3] += (long) dp[(i - 1) % 3] * (m - 2) % 1000000007;
dp[i % 3] %= 1000000007;
}
return dp[n % 3];
}
};
解法3:滚动数组另一个版本。
class Solution {
public:
/**
* @param n: the number of sectors
* @param m: the number of colors
* @return: The total number of plans.
*/
int getCount(int n, int m) {
int third = m;
int first = (long) third * (m - 1) % 1000000007;
int second = (long) first * (m - 2) % 1000000007;
// if (n == 1) return third;
if (n == 2) return first;
if (n == 3) return second;
for (int i = 4; i <= n; ++i) {
//if the first sector and the last sector are same color
third = (long) first * (m - 1) % 1000000007;
//if the first sector and the last sector are not same color
third += (long) second * (m - 2) % 1000000007;
third %= 1000000007;
first = second;
second = third;
}
return third;
}
};
探讨了在一个由n个扇区组成的圆上使用m种颜色进行染色的问题,确保相邻扇区颜色不同。通过动态规划算法,计算所有可能的染色方案总数,并采用滚动数组优化内存使用。
1302

被折叠的 条评论
为什么被折叠?



