2017浙江工业大学-校赛决赛 小M和天平

时间:2023-03-10 05:47:17
2017浙江工业大学-校赛决赛 小M和天平

Description

小M想知道某件物品的重量,但是摆在他面前的只有一个天平(没有游标)和一堆石子,石子可以放左边也可以放右边。他现在知道每个石子的重量。问能不能根据上述条件,能不能测出所问的重量。

Input

第一行T(1≤T≤100),表示T组数据。
接下来T组数据:
接下来第一行一个数N,表示石子个数。(1≤N≤100)
接下来第二行N个数,表示石子的重量。(1≤w_i≤100)
接下来第三行一个数M,表示询问个数。(1≤M≤100)
接下来M行每行一个数k,表示一个询问。

Output

对于每组数据,输出"YES"或者"NO"

Sample Input

1
2
1 4
3
2
4
5

Sample Output

NO
YES
YES
解法:
dp[i][j] 表示计算到第i个砝码,能计算j重量
首先dp[i][0]=1
5 2
1 第一个数字为5时,我们可以计算5的质量 dp[1][5]=dp[1-1][0+5]=1
2 第二个数字为2时,我们知道dp[2][7]=dp[2-1][7-2]=1或者是dp[2][3]=dp[2-1][5-2]=1 (当dp[1][5]==1时)
那么有
dp[i-1][j]==1时 dp[i][j]=1 dp[i][j+a[i]]=1 dp[i][abs(j-a[i])]=1
 #include<cstdio>
#include<algorithm>
#include<cstring>
#include<map>
#include<vector>
#include<iostream>
#include<sstream>
#include<cmath>
#include<string>
#include<set>
#include<list>
#include<stack>
#include<queue>
using namespace std;
int dp[][*+];
int main()
{
int t;
scanf("%d",&t);
while(t--){
int sum=;
int a[];
int n;
scanf("%d",&n);
memset(dp,,sizeof(dp));
for(int i=;i<=n;i++){
scanf("%d",&a[i]);
sum+=a[i];
}
for(int i=;i<=n;i++){
dp[i][]=;
}
for(int i=;i<=n;i++){
for(int j=sum;j>=;j--){
if(dp[i-][j]){
dp[i][j]=;
dp[i][abs(j-a[i])]=;
dp[i][j+a[i]]=;
}
}
}
int m;
scanf("%d",&m);
while(m--){
long long p;
scanf("%lld",&p);
if(dp[n][p]){
puts("YES");
}else{
puts("NO");
}
}
}
return ;
}