C. Phoenix and Towers
题目传送门:
题面:
题目大意:
贪心/优先队列。
给你n个小积木搭成m个塔使各个塔之间的高度差不超过x。
把塔的高度用优先队列维护, 每次取头,就是取高度最小的那个,把积木给他,最后任意两个塔的差值一定再x之内 最后使一定能保证的 所以没有NO。
简单来说就是构造差值最小的最优情况,如果此时满足则可以满足,此时都不满足就一定无法满足。
反思:
想了半天DP都D不出来,不能盲目DP。
代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 114514;
struct Node {
int x;
int sum;
bool operator<(const Node &a) const {
if (sum == a.sum) {
return x > a.x;
}
return sum > a.sum;
}
} node;
Node data1[maxn];
int h[maxn];
vector<Node> v;
int ans[maxn];
int main() {
ios::sync_with_stdio(false);
cin.tie(0), cout.tie(0);
int T;
cin >> T;
while (T--) {
int n, m, x;
cin >> n >> m >> x;
priority_queue<Node> q;
for (int i = 1; i <= m; i++) {
node.x = i;
node.sum = 0;
q.push(node);
}
for (int i = 1; i <= n; i++) {
cin >> h[i];
}
for (int i = 1; i <= n; i++) {
node = q.top();
node.sum += h[i];
ans[i] = node.x;
q.pop();
q.push(node);
}
Node mn = q.top();
while (q.size() != 1) {
q.pop();
}
Node mx = q.top();
// cout << mx.sum << " " << mn.sum << endl;
mx.sum -= mn.sum;
if (mx.sum <= x) {
cout << "yes" << endl;
for (int i = 1; i <= n; i++) {
cout << ans[i] << " ";
}
cout << endl;
} else {
cout << "no" << endl;
}
}
}