传送门:
http://acm.hdu.edu.cn/showproblem.php?pid=5616
题意:
砝码能拼重量问题,背包,很水,一发就过了,这个是开二维数组的背包,一会按照标解写个一维数组的正反背包!
#include<bits/stdc++.h>
using namespace std;
int a[25],dp[25][2050];
int t,n,m,k;
void solve(){
dp[0][0]=1;
for(int i=1;i<=n;i++){
for(int j=0;j<=2000;j++){
if(j-a[i]>=0&&dp[i-1][j-a[i]]) dp[i][j]=1;
if(dp[i-1][j]) dp[i][j]=1;
if(j+a[i]<=2000&&dp[i-1][j+a[i]]) dp[i][j]=1;
}
}
}
int main(){
cin>>t;
while(t--){
scanf("%d",&n);int sum=0;memset(dp,0,sizeof(dp));
for(int i=1;i<=n;i++) {
scanf("%d",&a[i]); sum+=a[i];
}
scanf("%d",&m);solve();
while(m--){
scanf("%d",&k);
if(k<0||k>sum||dp[n][k]==0){
puts("NO");continue;
}
puts("YES");
}
}
}
一维正反背包
#include <cstdio>
#include <cmath>
#include <iostream>
#include <cstdlib>
#include <algorithm>
#include <vector>
#include <map>
#include <set>
#include <cstring>
#include <string>
using namespace std;
typedef long long ll;
const int inf = 0x3f3f3f3f;
const int maxn = 20 + 5;
const int maxm = 2000 + 5;
int dp[maxm];
int A[maxn];
int N, M;
int main() {
cin.sync_with_stdio(false);
int T;
cin >> T;
while(T--) {
cin >> N;
for(int i = 0; i < N; i++) {
cin >> A[i];
}
//init
memset(dp, 0, sizeof(dp));
dp[0] = 1;
//positive
for(int i = 0; i < N; i++) {
for(int j = maxm - 1; j >= A[i]; j--) {
dp[j] |= dp[j - A[i]];
}
}
//negtive
for(int i = 0; i < N; i++) {
for(int j = 0; j < maxm - A[i]; j++) {
dp[j] |= dp[j+A[i]];
}
}
cin >> M;
for(int i = 0; i < M; i++) {
int k;
cin >> k;
if(dp[k]) {
cout << "YES" << endl;
} else {
cout << "NO" << endl;
}
}
}
return 0;
}
更有吊炸天的bitset写法orz!!!!
#include<bits/stdc++.h>
using namespace std;
int main()
{
int T;
scanf("%d",&T);
const int middle=2005;
while(T--)
{
int n,m;
scanf("%d",&n);
bitset<4015> dp;
dp[middle]=1;
for(int i=1;i<=n;i++)
{
int x;
scanf("%d",&x);
dp=dp|(dp<<x)|(dp>>x);
}
scanf("%d",&m);
while(m--)
{
int x;
scanf("%d",&x);
if(dp[middle-x]||dp[middle+x])
puts("YES");
else
puts("NO");
}
}
return 0;
}