被 Hack 的代码(包括我这次修改之前的题解):
# include <bits/stdc++.h>
# define old_six \
ios::sync_with_stdio (0);\
\
cin.tie (0);\
\
cout.tie (0);
# define ffor(i,name) \
for (auto i = name.begin (); i != name.end (); ++ i)
# define reg register
using namespace std;
typedef long long ll;
typedef pair <int, int> pii;
typedef pair <ll, ll> pll;
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) {
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 () {
old_six
cin >> n;
for (reg int i = 0; i < n; sum1 += max1[i], ++ i)
for (reg int j = 0; j <= i; ++ j)
cin >> a[i][j], max1[i] = max (max1[i], a[i][j]);
for (reg int i = 0; i < n; sum2 += max2[i], ++ i)
for (reg int j = 0; j <= i; ++ j)
max2[i] = max (max2[i], b[i][j] = a[n - j - 1][i - j]);
// for (reg int i = 0; i < n; ++ i, cout << '\n') for (reg int j = 0; j < n; ++ j) cout << b[i][j] << ' ';
for (reg int i = 0; i < n; sum3 += max3[i], ++ i)
for (reg 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});
// cout << sum1 << ' ' << sum2 << ' ' << sum3 << '\n';
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;
}
Hack 数据生成器:
# include <bits/stdc++.h>
using namespace std;
int main () {
ios::sync_with_stdio (0);
cin.tie (0);
cout.tie (0);
cout << "1000\n";
for (int i = 0; i < 1000; ++ i, cout << '\n')
for (int j = 0; j <= i; ++ j)
cout << "0 ";
return 0;
}
Hack 原理:
我使用的是记忆化递归,但是初值赋的是 0,而 ai,j 的值可以全部相同,这样可以使 dp1i,j 都变成 0,这时候记忆化递归的时间复杂度退化,退成了 2n 级别,足以导致 TLE