hdu5616

#include<cstdio>
#include<cstring>
const int maxm=2001;
const int mid=2005;
int a[21];
int dp[maxm+10];

int main()
{
    int T;
    scanf("%d",&T);
    while(T--){
        int n;
        scanf("%d",&n);
        for(int i=1;i<=n;i++)scanf("%d",&a[i]);
        memset(dp,0,sizeof(dp));
        dp[0]=1;
/** // for(int i=1;i<=n;i++){ // for(int j=a[i];j<=MAX;j++)dp[j]|=dp[j-a[i]];///a[i] j j-a[i] // 这里是因为理解有问题把我 如果j-a[i]可以 那么j就是可以得到的 // for(int j=a[i];j>=0;j--)dp[j]|=dp[a[i]+j]; // 如果j+a[i]可以 那么j就是可以得到的 // } // 但是我这里犯了错误 就是遍历的顺序弄错了 第一个应该是MAX到a[i] // 如果像我一样的遍历顺序 也就是说同样的a[i]重量 我使用了多次 与题意不符合 // ` 这里的砝码 是用且仅用一次的 */
        //positive
        for(int i = 1; i <= n; i++){
            for(int j = maxm - 1; j >= a[i]; j--){
                 dp[j] |= dp[j - a[i]];
            }
        }
        /** // for(int k=0;k<maxm;k++){ // if(dp[k]){ // printf("%d ",k); // } // } // printf("\n"); */
        //negtive
        for(int i = 1; i <=n; i++) {
            for(int j = 0; j < maxm - a[i]; j++) {
                dp[j] |= dp[j+a[i]];
            }
        }
// for(int i=0;i<maxm;i++){
// if(dp[i]){
// printf("%d ",i);
// }
// }
        int m;
        scanf("%d",&m);
        while(m--){
            int t;
            scanf("%d",&t);
            printf((t<=maxm&&(dp[t]))?"YES\n":"NO\n");
        }
    }
    return 0;
}

你可能感兴趣的:(hdu5616)