相邻房子不能同色,共有3种颜色
There are a row of n houses, each house can be painted with one of the three colors: red, blue or green. The cost of painting each house with a certain color is different. You have to paint all the houses such that no two adjacent houses have the same color.
The cost of painting each house with a certain color is represented by a
nx3cost matrix. For example,costs[0][0]is the cost of painting house 0 with color red;costs[1][2]is the cost of painting house 1 with color green, and so on... Find the minimum cost to paint all houses.Note:
All costs are positive integers.
int minCost(vector<vector<int>>& costs) {
// 设dp[i][c]表示前[0..i]房子、第i房颜色为c时的最小代价
// 有dp[i][c]=min(dp[i-1][not_c])+costs[i][c]
// 初始dp[0][c]=costs[0][c]
// 递推式在i维上只依赖i-1项,省掉i这维,i仍从左往右遍历
// c这维的依赖方向不确定,要用临时变量ndp[]
// ndp[c]=min(dp[not_c])+costs[i][c]
if (costs.empty()) return 0;
const int N = costs.size(), C = costs[0].size();
vector<int> dp = costs[0];
for (int i = 1; i < N; i++) {
vector<int> ndp(C);
for (int c = 0; c < C; c++) {
ndp[c] = min(dp[(c+1) % C], dp[(c+2) % C]) + costs[i][c];
}
swap(dp, ndp);
}
return min({dp[0], dp[1],dp[2]});
}
相邻房子不能同色,共有k种颜色
- https://leetcode.com/problems/paint-house-ii/
- https://leetcode.com/problems/minimum-falling-path-sum-ii/
There are a row of n houses, each house can be painted with one of the k colors. The cost of painting each house with a certain color is different. You have to paint all the houses such that no two adjacent houses have the same color.
The cost of painting each house with a certain color is represented by a
nxkcost matrix. For example,costs[0][0]is the cost of painting house 0 with color 0;costs[1][2]is the cost of painting house 1 with color 2, and so on... Find the minimum cost to paint all houses.Note:
All costs are positive integers.Follow up:
Could you solve it in O(nk) runtime?
同上题。可优化成O(nk)解法。
int minCostII(vector<vector<int>>& costs) {
// 设dp[i][c]表示前[0..i]房子、第i房颜色为c时的minCost
// dp[i][c] = min{ dp[i-1][not_c] } + costs[i][c],初始dp[0][c] = costs[0][c]
// 而求min{ dp[i-1][not_c] },只要维护dp[i-1][]的最小min1、取min1时的颜色min1c、以及第二小min2
// 这样 min{ dp[i-1][not_c] } = (c != min1c ? min1 : min2)
// dp[i][c] = (c != min1c ? min1 : min2) + costs[i][c]
// 所求为dp[N-1][]的最小min1
if (costs.empty()) return 0;
const int N = costs.size(), K = costs[0].size();
int min1 = 0, min1c = -1, min2 = 0;
for (int i = 0; i < N; i++) {
int tmp_min1 = INT_MAX, tmp_min1c = -1, tmp_min2 = INT_MAX; // dp[i][]对应的一组值
for (int c = 0; c < K; c++) {
int cost = (c != min1c ? min1 : min2) + costs[i][c];
if (cost < tmp_min1) {
tmp_min2 = tmp_min1;
tmp_min1 = cost;
tmp_min1c = c;
} else if (cost < tmp_min2) {
tmp_min2 = cost;
}
}
min1 = tmp_min1, min1c = tmp_min1c, min2 = tmp_min2;
}
return min1;
}
相邻3根栏杆不能同色
There is a fence with n posts, each post can be painted with one of the k colors.
You have to paint all the posts such that no 3 adjacent fence posts have the same color.
Return the total number of ways you can paint the fence.
Note:
n and k are non-negative integers.
int numWays(int n, int k) {
// 题目:不能有连续三根杆同色
// 漆第i新杆时,根据前两根杆同色或不同色分情况讨论。
// 设前两根同色的子问题的上色方式数为dp[i][0]
// 不同色 dp[i][1]
// 若新杆与前一根同色,则前两根不能同色,dp[i][0] = dp[i-1][1]
// 新杆与前一根不同色,则前两根可同色可不同色,新杆有k-1种选择
// dp[i][1] = (dp[i-1][0] + dp[i-1][1]) * (k-1)
// 递推式在i维上只依赖i-1项,省掉i这维
// ndp[0] = dp[1]
// ndp[1] = (dp[0] + dp[1]) * (k-1)
if (n == 0) return 0;
if (n == 1) return k;
vector<int> dp = { k, k * (k - 1) }; // n==2的情况
for (int i = 3; i <= n; i++) {
dp = { dp[1], (dp[0] + dp[1]) * (k - 1)};
}
return dp[0] + dp[1];
}