HDU 5616 Jam's balance

背包。dp[i]=1表示i这种差值能被组合出来,差值有负数,所以用sum表示0,0表示-sum,2*sum表示sum。

询问X的时候,只需看dp[sum+X]或者dp[sum-X]是否有一个为1,注意RE。

#include<cstdio>
#include<cstring>
#include<cmath>
#include<vector>
#include<algorithm>
#include<queue>
using namespace std;

int dp[8000];
int w[50];
int flag[8000];

int main()
{
    int T,N,M;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d",&N);
        memset(dp,0,sizeof dp);
        for(int i=1;i<=N;i++) scanf("%d",&w[i]);
        int sum=0;
        for(int i=1;i<=N;i++) sum=sum+w[i];
        dp[sum]=1;

        for(int i=1;i<=N;i++)
        {
            memset(flag,0,sizeof flag);
            for(int j=2*sum;j>=0;j--)
            {
                if(dp[j])
                {
                    if(j+w[i]<=2*sum) flag[j+w[i]]=1;
                    if(j-w[i]>=0) flag[(j-w[i])]=1;
                }
            }
            for(int i=0;i<=2*sum;i++) if(flag[i]) dp[i]=1;
        }

        scanf("%d",&M);
        for(int i=1;i<=M;i++)
        {
            int x;
            scanf("%d",&x);
            if(x>sum||x<0) printf("NO\n");
            else
            {
                if(dp[sum+x]==1||(sum-x>=0&&dp[sum-x]==1)) printf("YES\n");
                else printf("NO\n");
            }
        }
    }
    return 0;
}

 

posted @ 2016-02-02 09:17  Fighting_Heart  阅读(401)  评论(0编辑  收藏  举报