题目链接
题意
给定
n
(
此外,这
n
个数还满足一些特殊条件:
1.
2.
ai≤∑j=1i−1aj[bj=N]+∑j=1i−1aj[bi=L∩bj=L]+∑j=1i−1aj[bi=D∩bj=D](2≤i≤n).
玄学?非也
比赛时破罐子破摔直接判断
k
在不在左右两个端点范围内,竟然就过了,然而这是为什么呢?
结论
这道题中的数能组成的数构成了一个连续区间.
证明
关注一下上面的两个条件,由条件
不妨设处理到第 i 个元素结束时可以连续取到的范围为
[Lo,Hi]
, 显然有
Lo=−(∑bj=N∩j≤iaj+∑bj=Daj),Hi=∑bj=N∩j≤iaj+∑bj=Laj.
1. 假设第 i+1 个元素的属性为 L ,
则根据条件
又 [0,Hi]+ai=[ai,Hi+ai] ,有 ai≤Hi ,故 [Hi,Hi+ai]⊆[ai,Hi+ai] ,
原范围 ∪ 新范围即为 [Lo,Hi]∪[Hi,Hi+ai]=[Lo,Hi+ai] ,且连续
2. 假设第 i+1 个元素的属性为 D ,
与上同理
3. 假设第
则根据条件
由数学归纳法得: 这道题中的数能组成的数构成了一个连续区间.
所以上面的玄学做法(大雾)就是有理有据的了
Code
#include <bits/stdc++.h>
#define maxn 1010
#define maxl 2000010
typedef long long LL;
const LL mod = 1e9 + 7;
inline int max(int a, int b) { return a > b ? a : b; }
inline int min(int a, int b) { return a < b ? a : b; }
int a[maxn], id[maxn]; char c;
bool dp[maxl];
void work() {
memset(dp, 0, sizeof(dp));
int n, k;
scanf("%d%d", &n, &k);
for (int i = 0; i < n; ++i) scanf("%d", &a[i]);
scanf("\n%c", &c);
int netu = a[0], nega = 0, posi = 0;
for (int i = 1; i < n; ++i) {
scanf(" %c", &c);
if (c == 'L') posi += a[i];
else if (c == 'D') nega -= a[i];
else netu += a[i];
}
int le = nega - netu, ri = posi + netu;
if (k < le || k > ri) {
printf("no\n");
return;
}
printf("yes\n");
}
int main() {
int T;
scanf("%d", &T);
while (T--) work();
return 0;
}