[编程题]堆棋子 中位数
https://www.nowcoder.com/questionTerminal/27f3672f17f94a289f3de86b69f8a25b
由于x[]和y[]是独立的,所以贡献可以单独考虑
如果选出k个,x[1...k]
那么肯定是去到中位数那个点,所需要的贡献是最小的。
那么就有n^2种不同的目标点,也就是每个x,对应每个y。
然后枚举每一个点到达这个点所需要的最小距离,取个最小的即可。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include <bits/stdc++.h> #define IOS ios::sync_with_stdio(false) using namespace std; #define inf (0x3f3f3f3f) typedef long long int LL; const int maxn = 50 + 20; int x[maxn], y[maxn]; int xx[maxn], yy[maxn]; LL sum[52][52][52]; void work() { int n; cin >> n; for (int i = 1; i <= n; ++i) { cin >> x[i]; xx[i] = x[i]; } for (int i = 1; i <= n; ++i) { cin >> y[i]; yy[i] = y[i]; } for (int i = 1; i <= n; ++i) { for (int j = 1; j <= n; ++j) { for (int k = 1; k <= n; ++k) { sum[i][j][k] = abs(x[k] - x[i]) + abs(y[k] - y[j]); } sort(sum[i][j] + 1, sum[i][j] + 1 + n); for (int k = 2; k <= n; ++k) { sum[i][j][k] += sum[i][j][k - 1]; } } } for (int i = 1; i <= n; ++i) { LL ans = 1e18; for (int one = 1; one <= n; ++one) { for (int two = 1; two <= n; ++two) { ans = min(ans, sum[one][two][i]); } } if (i < n) cout << ans << " "; else cout << ans << endl; } } int main() { #ifdef local freopen("data.txt", "r", stdin); // freopen("data.txt", "w", stdout); #endif work(); return 0; }
既然选择了远方,就要风雨兼程~
posted on 2017-12-15 23:11 stupid_one 阅读(205) 评论(0) 编辑 收藏 举报