P9541 题解
思路
一个三角形转三次会变回原来的样子,所以这题的旋转次数最多只有 次,再上去肯定不是最优的,这样我们就可以分成三种情况考虑。但实际上我们只要考虑不旋转的情况,剩余的几乎是 Ctrl+C。
剩余部分很像数字三角形,我们也可以往下方走或右下方走。这题中,我们一定存在一种方案,可以使经过的数字总和为 ,所以如果 ,则需要额外消耗 点消耗值。 同理,最后只要在往下方和右下方方向走的消耗值取个 即可。
代码
# include <bits/stdc++.h>
using namespace std;
int n, a[1005][1005], b[1005][1005], c[1005][1005], dp1[1005][1005], dp2[1005][1005], dp3[1005][1005], sum1, sum2, sum3, max1[1005], max2[1005], max3[1005], maxx, minx = 1e9;
int dfs1 (int x, int y) {
if (~ dp1[x][y]) //记忆化递归
return dp1[x][y];
if (x > n - 2) //最后一行了,结束递归
return 0;
return dp1[x][y] = min (dfs1 (x + 1, y) + (a[x + 1][y] != max1[x + 1]), dfs1 (x + 1, y + 1) + (a[x + 1][y + 1] != max1[x + 1]));
}
int dfs2 (int x, int y) { //什么是 Ctrl+C?
if (~ dp2[x][y])
return dp2[x][y];
if (x > n - 2)
return 0;
return dp2[x][y] = min (dfs2 (x + 1, y) + (b[x + 1][y] != max2[x + 1]), dfs2 (x + 1, y + 1) + (b[x + 1][y + 1] != max2[x + 1]));
}
int dfs3 (int x, int y) {
if (~ dp3[x][y])
return dp3[x][y];
if (x > n - 2)
return 0;
return dp3[x][y] = min (dfs3 (x + 1, y) + (c[x + 1][y] != max3[x + 1]), dfs3 (x + 1, y + 1) + (c[x + 1][y + 1] != max3[x + 1]));
}
int main () {
cin >> n;
for (int i = 0; i < n; sum1 += max1[i], ++ i)
for (int j = 0; j <= i; ++ j)
cin >> a[i][j], max1[i] = max (max1[i], a[i][j]), dp1[i][j] = dp2[i][j] = dp3[i][j] = -1);
for (int i = 0; i < n; sum2 += max2[i], ++ i)
for (int j = 0; j <= i; ++ j)
max2[i] = max (max2[i], b[i][j] = a[n - j - 1][i - j]);
for (int i = 0; i < n; sum3 += max3[i], ++ i)
for (int j = 0; j <= i; ++ j)
max3[i] = max (max3[i], c[i][j] = b[n - j - 1][i - j]);
maxx = max ({sum1, sum2, sum3});
if (maxx == sum1)
minx = dfs1 (0, 0);
if (maxx == sum2)
minx = min (minx, dfs2 (0, 0) + n);
if (maxx == sum3)
minx = min (minx, dfs3 (0, 0) + n * 2);
cout << maxx << ' ' << minx;
return 0;
}

浙公网安备 33010602011771号