Problem Description
Jim has a balance and N weights. (1 \leq N \leq 20)(1≤N≤20) The balance can only tell whether things on different side are the same weight. Weights can be put on left side or right side arbitrarily. Please tell whether the balance can measure an object of weight M.
Input
The first line is a integer T(1 \leq T \leq 5)T(1≤T≤5), means T test cases. For each test case : The first line is NN, means the number of weights. The second line are NN number, i'th number w_i (1 \leq w_i \leq 100)wi(1≤wi≤100) means the i'th weight's weight is w_iwi. The third line is a number MM. MM is the weight of the object being measured.
Output
You should output the "YES"or"NO".
Sample Input
1 2 1 4 3 2 4 5
Sample Output
NO YES YESHintFor the Case 1:Put the 4 weight aloneFor the Case 2:Put the 4 weight and 1 weight on both side
对DP熟悉,还是要多练习一下,都没有下意识的想用DP。
#include <iostream> #include <algorithm> #include <cstdio> #include <cmath> #include <string> #include <cstring> #include <set> #include <queue> #include <cstdlib> using namespace std; typedef long long LL; const int maxn = 1e5 + 10; int T, n, m, dp[21][4005], x; int main() { scanf("%d",&T); while(T--) { scanf("%d",&n); memset(dp, 0, sizeof(dp)); dp[0][2000]=1; for(int i=0;i<n;i++) { scanf("%d", &x); for(int j=x;j<=4000-x;j++) if(dp[i][j]) dp[i+1][j-x]=dp[i+1][j+x]=dp[i+1][j]=1;//不断对可能取到的重量做标记 } scanf("%d",&m); while(m--) { scanf("%d",&x); if(x>=0&&x<=2000) { if(dp[n][2000-x]||dp[n][2000+x]) printf("YES\n"); else printf("NO\n"); } } } return 0; }