首页 > 代码库 > 2017浙江工业大学-校赛决赛 小M和天平

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
 1 #include<cstdio>
 2 #include<algorithm>
 3 #include<cstring>
 4 #include<map>
 5 #include<vector>
 6 #include<iostream>
 7 #include<sstream>
 8 #include<cmath>
 9 #include<string>
10 #include<set>
11 #include<list>
12 #include<stack>
13 #include<queue>
14 using namespace std;
15 int dp[200][100*100+10];
16 int main()
17 {
18     int t;
19     scanf("%d",&t);
20     while(t--){
21         int sum=0;
22         int a[200];
23         int n;
24         scanf("%d",&n);
25         memset(dp,0,sizeof(dp));
26         for(int i=1;i<=n;i++){
27             scanf("%d",&a[i]);
28             sum+=a[i];
29         }
30         for(int i=0;i<=n;i++){
31             dp[i][0]=1;
32         }
33         for(int i=1;i<=n;i++){
34             for(int j=sum;j>=0;j--){
35                 if(dp[i-1][j]){
36                     dp[i][j]=1;
37                     dp[i][abs(j-a[i])]=1;
38                     dp[i][j+a[i]]=1;
39                 }
40             }
41         }
42         int m;
43         scanf("%d",&m);
44         while(m--){
45             long long p;
46             scanf("%lld",&p);
47             if(dp[n][p]){
48                 puts("YES");
49             }else{
50                 puts("NO");
51             }
52         }
53     }
54     return 0;
55 }

 

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