B:
Jam's balance
Accepts: 143
Submissions: 880
Time Limit: 2000/1000 MS (Java/Others)
Memory Limit: 65536/65536 K (Java/Others)
NO YES YESHintFor the Case 1:Put the 4 weight alone For the Case 2:Put the 4 weight and 1 weight on both side
之前在省赛中做过类似的题目 不过上次是暴力 这次需要DP来优化
CODE:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <algorithm>
using namespace std;
int fn;
int hash[105][105],dp[30][2005],x,y,MAX,n[30],sum;
int wtf[2005];
int cmp(int x,int y)
{
return x>y;
}
void solve()
{
int i,j,k,l,w;
memset(dp,0,sizeof(dp));
dp[0][0] = 1;
int ans = 0;
for(i = 1; i<=fn; i++)
{
w = n[i];
memcpy(dp[i],dp[i-1],sizeof(dp[0]));
for(j = sum; j>0; j--)
{
if(j>=w)//可以放置,差j-w
{
if(dp[i-1][j-w])//补成j
dp[i][j] = 1;
if(dp[i-1][j])//差j-w
dp[i][j-w] = 1;
}
else
{
if(dp[i-1][j])//差w-j
{
dp[i-1][w-j] = 1;
dp[i][w-j]=1;
}
}
}
}
for(i = 1; i<=sum; i++)
{
if(dp[ fn ][i])
{
wtf[ i]=1;
ans++;
}
}
if(ans>MAX)
MAX = ans;
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
memset(wtf,0,sizeof(wtf));
int i,j;
sum=0;
scanf("%d",&fn);
for(i=1;i<=fn;i++)
{
scanf("%d",&n[i]);
sum+=n[i];
}
MAX = 0;
solve();
int m;
scanf("%d",&m);
while(m--)
{
int fff;
scanf("%d",&fff);
if(fff>2000)
{
printf("NO\n");
continue;
}
if(wtf[fff])
printf("YES\n");
else
printf("NO\n");
}
}
return 0;
}