解题思路

很显然的贪心题,只需要判断每一个路程耗电量的大小进行选择即可,但是这道题同样可以用 DP 做(其实思路是一样的)。

我们定义一个数组 dpdp 表示到第 wiw_i 时候所耗费的最小电量,由于 dpidp_i 只可以通过 dpi1dp_{i - 1} 转移而来,并且分为两种情况:一直打开或者先关机后打开。可以得到:

dpi=min(dpi1+(wiwi1)×a,dpi1+b)dp_i = \min(dp_i - 1 + (w_i - w_{i - 1}) \times a, dp_{i - 1} + b)

这时候便可以愉快的写代码了。

AC Code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
// Problem: C. Sending Messages
// Contest: Codeforces - Codeforces Round 920 (Div. 3)
// URL: https://codeforces.com/contest/1921/problem/C
// Memory Limit: 256 MB
// Time Limit: 2000 ms
//
// Powered by CP Editor (https://cpeditor.org)

#include <bits/stdc++.h>

using namespace std;

#define int long long

typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> PII;

const int N = 2e5 + 9;
const int INF = 0x3f3f3f3f;

int w[N], dp[N]; // 第 i 个表示在w[i]时刻所用的电量的最小值

void solve()
{
memset(dp, 0x3f, sizeof dp);
int n, f, a, b; cin >> n >> f >> a >> b;
for (int i = 1; i <= n; i ++) cin >> w[i];
for (int i = 1; i <= n; i ++)
dp[i] = min(dp[i - 1] + b, dp[i - 1] + a * (w[i] - w[i - 1]));
if (dp[n] >= f) cout << "NO\n";
else cout << "YES\n";
}

signed main()
{
// ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
int T; cin >> T;
while (T --) solve();
return 0;
}