题意
给出n个(n <= 20)物品的重量, 问这堆物品能否划分为重量相同的两堆。
解题
典型的动态规划题目,求子集元素和。将给出的数据同时视为物品的重量和价值,输入时计算所有重量和sum。然后dp求出不同重量下能得到的最大物品价值,最后判断sum - 2 * dp[sum / 2] 是否为0即可。
AC-Code
#include <cstdio>
#include <cstring>
int dp[210];
int v[21];
int main(){
// freopen("i.txt", "r", stdin);// freopen("o.txt", "w", stdout);int t; scanf("%d", &t);getchar();while(t--){
int num, sum = 0, cnt = 0;char c;while(scanf("%d%c", &num, &c)){
v[cnt++] = num;sum += num;if(c == '\n') break;}memset(dp, 0, sizeof(dp));for(int i = 0; i < cnt; i++)for(int j = sum / 2; j >= v[i]; j--)if(dp[j] < dp[j - v[i]] + v[i])dp[j] = dp[j - v[i]] + v[i];puts((sum - 2 * dp[sum / 2] == 0)? "YES" : "NO");}
}