题目大意
给出一串正数 ai ,每个数有一个属性:N、L或D
N表示这个数的符号可正可负;L表示这个数的符号是正;D表示符号为负
这些数满足:a1=1,b1=N
ai≤∑j=1i−1aj[bj=N]+∑j=1i−1aj[bi=L∩bj=L]+∑j=1i−1aj[bi=D∩bj=D](2≤i≤n).>
现在给你一个数k,问你是否可以由这些数构成k分析
这道题如果把题意读懂了就不难了
不难发现和证明:
从1到(N和L属性的所有数的和)这个区间中的每个数都能通过组合得到到
(N和D属性的所有数的和)到-1这个区间所有数都能通过组合得到到
需要说明的一点是N属性可以当作正和负两个数来用,因为这两个数同时用的时候就相当于没选这个数代码
#include<cstdio>
#include<iostream>
#include<cmath>
#include<cstring>
#include<cstdlib>
#include<queue>
#include<map>
#include<algorithm>
#include<set>
#include<stack>
using namespace std;
#define LL long long int
const int MAXN=1008;
const long long int MOD=1000000007;
int T;
int n,k;
int a[MAXN];
char b[MAXN];
void In()
{
char c;
for(int i=1;i<=n;i++)scanf("%d",&a[i]);
for(int i=1;i<=n;i++)
{
scanf("%c",&c);
while(c==' ' || c=='\n')scanf("%c",&c);
b[i]=c;
}
}
void Work()
{
int maxm=0,minm=0;
for(int i=1;i<=n;i++)
{
if(b[i]=='N'){maxm+=a[i];minm-=a[i];}
else if(b[i]=='L')maxm+=a[i];
else minm-=a[i];
}
if(k<=maxm && k>=minm)printf("yes\n");
else printf("no\n");
}
int main()
{
scanf("%d",&T);
while(T--)
{
scanf("%d%d",&n,&k);
In();
Work();
}
return 0;
}