您的位置:首页 > 其它

BestCoder Round #70 1002 Jam's balance(DP)

2016-01-30 22:57 555 查看
题意:见题目

思路:这题比赛的时候做不出来...赛后看了下题解,没有想到是01背包的思想。如果全部砝码放在右边那么最重可以有2000个重量,由于左右都可以放,所以我们开dp[25][4005]的数组,将2000作为平衡点,转移方程见代码

#include<cstdio>
#include <queue>
#include <cstring>
#include <iostream>
#include <cstdlib>
#include <algorithm>
#include <vector>
#include <map>
#include <string>
#include <set>
#include <ctime>
#include <cmath>
#include <cctype>
using namespace std;
#define maxn 100000
#define LL long long
int cas=1,T;

int dp[25][4005];
int main()
{
//freopen("in","r",stdin);
scanf("%d",&T);
while (T--)
{
int n;
int s=0;
int w[25];
scanf("%d",&n);
for (int i = 1;i<=n;i++)
{
scanf("%d",&w[i]);
s+=w[i];
}
memset(dp,0,sizeof(dp));
dp[0][2000]=1;
for (int i = 1;i<=n;i++)
for (int j = 4000;j>=0;j--)
{                                      //设dp[i][j]表示用了i个砝码称j重量是否可行
if (dp[i-1][j])                    //转移一,如果只用了i-1个砝码就称出了j,那么多加一个砝码也足够称出j
dp[i][j]=1;
if (j+w[i]<=4000 && dp[i-1][j])    //转移二,如果用i-1个砝码称出了j,那么我在右边多加一个砝码,就可以称出j+w[i]
dp[i][j+w[i]]=1;
if (j-w[i]>=2000 && dp[i-1][j])    //转移三,如果用i-1个砝码称出了j,那么我在左边多加一个砝码,就可以称出j-w[i]
dp[i][j-w[i]]=1;
}
int q;
scanf("%d",&q);
while (q--)
{
int x;
scanf("%d",&x);
if (!dp
[x+2000] || x>s)
puts("NO");
else
puts("YES");
}
}
//printf("time=%.3lf",(double)clock()/CLOCKS_PER_SEC);
return 0;
}


题目

问题描述
Jam有NN个砝码和一个没有游标的天平,现在给他(1 \leq N \leq 20)(1≤N≤20)个砝码,砝码可以放左边,也可以放右边,问可不可以测出所问的重量, 问的个数为(1 \leq M \leq 100)(1≤M≤100)个.


输入描述
第一行T(1 \leq T \leq 5)T(1≤T≤5),表示TT组数据。
接下来TT组数据:
接下来第一行一个数NN,表示砝码个数。
接下来第二行NN个数,表示砝码们的重量(1 \leq w_i \leq 100)(1≤w​i​​≤100)。
接下来第三行一个数MM,表示询问个数。
接下来MM行每行一个数kk,表示一个询问。


输出描述
对于每组数据,输出"YES"或者"NO"


输入样例
1
2
1 4
3
2
4
5


输出样例
NO
YES
YES


Hint
单独放4,可以测出重量为4的
在同一边放4,1,可以测出重量为5的
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: