类似背包的dp【】转移方程 但并不是背包求最大的问题 。
http://acm.hdu.edu.cn/showproblem.php?pid=5616
首先要正的扫一遍,就是物品那端不放砝码,只在另一端放砝码,看有多少重量可以放到(这里记录的是该重量能否被访问到,所以不需要搞什么max)
之后就是反着扫一遍,在上面处理的dp结果减去相应的砝码就ok了,比如减去a[i],如果dp[j]已经算了a[i],那就想到与不算a[i]咯,有人可能陷入死胡同,想对于j要计算吧a[i]放在物品那边咋办,在dp[j-a[i]]中不就计算了这个问题。如果没有算a[i],那就是减去a[i]咯.
The first line is a integer T(1≤T≤5), means T test cases.
For each test case :
The first line is N, means the number of weights.
The second line are N number, i'th number wi(1≤wi≤100) means the i'th weight's weight is wi.
The third line is a number M. M
is the weight of the object being measured
#include<bits/stdc++.h> #define maxn 100004 int dp[maxn]; int weigh[maxn]; int n,m,t; using namespace std; int main() { cin>>t; while(t--) { cin>>n; for(int i=0; i<n; i++) cin>>weigh[i]; memset(dp,0,sizeof(dp)); dp[0]=1; for(int i=0; i<n; i++) for(int j=2005; j>=weigh[i]; j--) dp[j]|=dp[j-weigh[i]]; for(int i=0; i<n; i++) for(int j=weigh[i]; j<=2005; j++) dp[j-weigh[i]]|=dp[j]; cin>>m; while(m--) { int ans; cin>>ans; if(dp[ans]) cout<<"YES"<<endl; else cout<<"NO"<<endl; } } return 0; }
#include<bits/stdc++.h> #define maxn 100004 int dp[maxn]; int weigh[maxn]; int n,m,t; using namespace std; int main() { cin>>t; while(t--) { cin>>n; for(int i=0; i<n; i++) cin>>weigh[i]; memset(dp,0,sizeof(dp)); dp[0]=1; for(int i=0; i<n; i++) for(int j=2005; j>=weigh[i]; j--) { if(dp[j]==1||dp[j-weigh[i]]==1) dp[j]=1; } for(int i=0; i<n; i++) for(int j=weigh[i]; j<=2005; j++) { if(dp[j]==1||dp[j-weigh[i]]==1) dp[j-weigh[i]]=1; } cin>>m; while(m--) { int ans; cin>>ans; if(dp[ans]) cout<<"YES"<<endl; else cout<<"NO"<<endl; } } return 0; }
.