解题思路:
- 输入时记录数组和sum, 如果sum%2=0直接输出
false
- 否则令dpj(01背包),(0≤j≤sum/2),表示处理第i个数时,容量为j的背包,问题变为使用i和上一轮的值是否能构成j。
状态转移方程:
dpj=1,(j=vi or dpj−vi=0)
- 最后根据dpsum/2的值是否为1输出
true
或false
#include<bits/stdc++.h>
using namespace std;
int main(){
int n;
ios::sync_with_stdio(false);
cin>>n;
vector<int> v(n+1);
int sum = 0;
for(int i = 1; i <= n; ++i){
cin>>v[i];
sum += v[i];
}
int flag = 1;
if(sum % 2 != 0) flag = 0;
else {
vector<int> dp(sum/2+1);
for(int i = 1; i <= n; ++i){
for(int j = sum/2; j >= v[i]; --j){
if(j == v[i] || dp[j-v[i]] != 0) dp[j] = 1;
else dp[j] = 0;
}
}
flag = dp[sum/2];
}
cout<<(flag? "true": "false")<<endl;
return 0;
}