砝码称重
DP不是有记忆的贪心,本质是有记忆的递归,背包问题中只是把递归的结果挑选出符合题意的最大来记忆,而这道题就不是最大容重啥的了,dp[i][j]就是记录前i个砝码能不能称出重量为j的物品,不管它是怎么凑的,只挑选结果记忆,而不是重新递归求解
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
//动态规划 构建一个二维数组 dp[i][target] 表示从考虑前i个砝码的时候 能否构建成和为target的真假值
void judge(int sum,vector<int>& weight,vector<int>&target){
int n=weight.size()-1; //n个砝码
int dp[n+1][sum]={0}; //dp[0][j]=0
for(int i=0;i<n;++i) //target=0则不用砝码也可称出
dp[i][0]=1;
for(int i=1;i<=n;++i){ //考虑1-n个砝码
for(int j=1;j<=sum;++j){
dp[i][j]=dp[i-1][j]||dp[i-1][j+weight[i]]||dp[i-1][abs(j-weight[i])];
}
}
for(int i=0;i<target.size();++i){
printf("%d",dp[n][target[i]]);
}
}
int main() {
int n,q,t;
cin>>t;
while(t--){
cin>>n;
vector<int>weight(n+1);
for(int i=1;i<=n;++i)
scanf("%d",&weight[i]);
cin>>q;
vector<int>target(q);
int sum=0;
for(int i=0;i<q;++i){
scanf("%d",&target[i]);
sum+=target[i];
}
judge(sum,weight,target);
printf("\n");
}
system("pause");
return 0;
}