5 条题解
-
19
可能因为水平问题,萌新会看不懂列位大佬的
装bi代码,所以我结合他们的思路又重新编了一套较为简易的AC代码。#include <bits/stdc++.h> using namespace std; int n,f[100001][3],costs[1000001][3]; int main() { cin >> n; for(int i = 1;i <= n;i++){ cin >> costs[i][0] >> costs[i][1] >> costs[i][2]; } f[1][0] = costs[1][0]; f[1][1] = costs[1][1]; f[1][2] = costs[1][2]; for (int i=2;i<=n;i++){ f[i][0]=min(f[i-1][1],f[i-1][2])+costs[i][0]; f[i][1]=min(f[i-1][2],f[i-1][0])+costs[i][1]; f[i][2]=min(f[i-1][0],f[i-1][1])+costs[i][2]; } cout << min(min(f[n][0],f[n][1]),f[n][2]); return 0; }
一个赞抱走~~ ❤️ ❤️ ❤️
-
3
#include <bits/stdc++.h> using namespace std; int n,ans=INT_MAX; struct Node{ int red,blue,green; }; vector<Node>v; int f[10010][5]; int main(){ cin>>n; vector<Node>v(n,{0,0,0}); for (int i=0;i<n;i++)cin>>v[i].red>>v[i].blue>>v[i].green; f[1][0]=v[0].red; f[1][1]=v[0].blue; f[1][2]=v[0].green; for (int i=2;i<=n;i++){ f[i][0]=min(f[i-1][1],f[i-1][2])+v[i-1].red; f[i][1]=min(f[i-1][2],f[i-1][0])+v[i-1].blue; f[i][2]=min(f[i-1][0],f[i-1][1])+v[i-1].green; } cout<<min(min(f[n][0],f[n][1]),f[n][2]); return 0; }
-
2
解析
这是一个动态规划问题。我们可以使用一个三维数组 dp 来存储状态,其中 dp[i][j][k] 表示当前房子为第 i 栋,且前一栋房子的颜色为 j,当前房子的颜色为 k 时的最小花费。我们需要遍历所有可能的状态,更新 dp 数组,最后返回 dp[n] + dp[n] + dp[n] 作为答案。
代码如下:
#include <iostream> #include <vector> #include <algorithm> using namespace std; int main() { int n; cin >> n; vector<vector<vector<int>>> costs(n + 1, vector<vector<int>>(3, vector<int>(3))); for (int i = 1; i <= n; ++i) { for (int j = 0; j < 3; ++j) { cin >> costs[i][j]; } } for (int i = 1; i <= n; ++i) { for (int j = 0; j < 3; ++j) { for (int k = 0; k < 3; ++k) { costs[i][j][k] += min(costs[i - 1][(j + 1) % 3][k], costs[i - 1][(j + 2) % 3][k]); } } } cout << costs[n] + costs[n] + costs[n] << endl; return 0; }
-
0
每栋房子的粉刷情况都有三种可能,可以用0,1,2来分别表示红色,蓝色,绿色 f[i][0]:表示粉刷到第i栋房子时,该位置粉刷成红色,此时的最少花费是多少。 f[i][1]:表示粉刷到第i栋房子时,该位置粉刷成蓝色,此时的最少花费是多少 f[i][2]:表示粉刷到第i栋房子时,该位置粉刷成绿色,此时的最少花费是多少。 状态转移时注意相邻两栋房子颜色不能相同即可。
参考代码
for (int i = 1; i <= n; i++) { f[i][0] = min(f[i - 1][1], f[i - 1][2]) + costs[i][0]; f[i][1] = min(f[i - 1][0], f[i - 1][2]) + costs[i][1]; f[i][2] = min(f[i - 1][0], f[i - 1][1]) + costs[i][2]; }
-
-1
题目要求粉刷房子,使得相邻的两个房子颜色不能相同,并给出了每个房子粉刷成不同颜色的花费。
我们可以使用动态规划来解决这个问题。设f[i][j]表示粉刷到第i栋房子时,第i栋房子颜色为j时的最小花费。
根据题目要求,对于每一栋房子i,它可以被粉刷成红色、蓝色或绿色,所以有以下状态转移方程:
f[i][0] = costs[i][0] + min(f[i-1][1], f[i-1][2]) f[i][1] = costs[i][1] + min(f[i-1][0], f[i-1][2]) f[i][2] = costs[i][2] + min(f[i-1][0], f[i-1][1])
其中,costs[i][j]表示将第i栋房子粉刷成颜色j需要的花费。
最终的结果就是f[n-1][0]、f[n-1][1]和f[n-1][2]中的最小值,其中n为房子的数量。
#include <iostream> #include <vector> #include <climits> using namespace std; int minCost(vector<vector<int>>& costs) { int n = costs.size(); if (n == 0) { return 0; } vector<vector<int>> dp(n, vector<int>(3, 0)); dp[0] = costs[0]; for (int i = 1; i < n; i++) { dp[i][0] = min(dp[i-1][1], dp[i-1][2]) + costs[i][0]; dp[i][1] = min(dp[i-1][0], dp[i-1][2]) + costs[i][1]; dp[i][2] = min(dp[i-1][0], dp[i-1][1]) + costs[i][2]; } return min(min(dp[n-1][0], dp[n-1][1]), dp[n-1][2]); } int main() { int n; cin >> n; vector<vector<int>> costs(n, vector<int>(3)); for (int i = 0; i < n; i++) { for (int j = 0; j < 3; j++) { cin >> costs[i][j]; } } int result = minCost(costs); cout << result << endl; return 0; }
- 1
信息
- ID
- 349
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 1
- 标签
- (无)
- 递交数
- 462
- 已通过
- 308
- 上传者