小M和天平 题解(背包)
题目链接
题目思路
注意石子可以摆到两边
则一个石子可以为a[i] 0 -a[i]
则背包直接背就行
把初始重量直接变成1e4
代码
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e2+5;
int n,k;
int a[maxn];
int dp[maxn][20000+500];
int main(){
int mid=1e4;
while(scanf("%d",&n)!=-1){
int ma=0;
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
ma+=a[i];
}
dp[0][mid]=1;
for(int i=1;i<=n;i++){// a[i] -a[i] 0
for(int j=mid-ma;j<=mid+ma;j++){
if(dp[i-1][j]){
dp[i][j]=dp[i][j+a[i]]=dp[i][j-a[i]]=1;
}
}
}
int _;scanf("%d",&_);
while(_--){
scanf("%d",&k);
printf((k<=1e4&&dp[n][k+mid])?"YES\n":"NO\n");
}
for(int i=1;i<=n;i++){//
for(int j=mid-ma;j<=mid+ma;j++){
dp[i][j]=0;
}
}
}
return 0;
}
还有一种方法其实-a[i] 就等于\(f[i][abs(j-a[i])]\)
代码
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e2+5;
int n,k;
int a[maxn];
int dp[maxn][10000+500];
int main(){
while(scanf("%d",&n)!=-1){
int ma=0;
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
ma+=a[i];
}
dp[0][0]=1;
for(int i=1;i<=n;i++){//
for(int j=0;j<=ma;j++){
if(dp[i-1][j]){
dp[i][j]=dp[i][j+a[i]]=dp[i][abs(j-a[i])]=1;
}
}
}
int _;scanf("%d",&_);
while(_--){
scanf("%d",&k);
printf((k<=1e4&&dp[n][k])?"YES\n":"NO\n");
}
for(int i=1;i<=n;i++){//
for(int j=0;j<=ma;j++){
dp[i][j]=0;
}
}
}
return 0;
}
不摆烂了,写题