题意:有n堆方块,每堆方块高度为hi,表示这堆方块里有多少个方块,角色从第1堆顶开始移动,可以进行三种操作:取走当前顶部t个方块;在当前顶部放t个方块(不超过当前持有方块数);若下一堆与当前堆高度差绝对值不超过k,则可以向前移动。给出初始持有方块m,求是否可以从1到达n
思路:其实是简单题,昨天没耐心去想,主要是贪心求解。若当前堆高于下一堆,那就从当前堆取出使两堆高度差恰好达到k的方块,使得当前堆低于下一堆(取尽量多);若下一堆与当前堆高度差不超过k,也可以从当前堆取出部分方块使高度恰好等于k;若高度差高于k,判断是否当前持有格子足以叠放使得满足移动条件,能则移动,不能输出失败;若操作过后当前堆为n堆,则输出成功
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<vector>
#include<queue>
using namespace std;
typedef long long ll;
const int maxn = 1e3+5;
const int inf = 0x3f3f3f3f;
int n, m, k, T, h[maxn];
int main()
{
cin >> T;
for (int t = 1; t <= T; t++) {
cin >> n >> m >> k;
for (int i = 1; i <= n; i++)
cin >> h[i];
if (n == 1) {
cout << "YES" << endl;
continue;
}
int cur = 1;
for (int i = 2; i <= n; i++) {
if (h[cur] > h[i]) {
int t = h[cur] - h[i] + k;
if (t > h[cur])
t = h[cur];
m += t;
cur++;
}
else if (h[i]-h[cur] <= k) {
int t = k - h[i] + h[cur];
if (t > h[cur])
t = h[cur];
m += t;
cur++;
}
else if (h[i]-h[cur] <= k+m){
m -= h[i] - h[cur] - k;
cur++;
}
else {
cout << "NO" << endl;
break;
}
}
if (cur == n)
cout << "YES" << endl;
}
return 0;
}