题目链接:点击打开链接
题意:n个硬币,给出每个硬币的价值,要求把这些硬币分成两组,使得两组的价值差尽量小。
可以发现如果可以平分,那么价值差肯定为0,那么依次从sum/2 --> 0 枚举i,如果用上述硬币的价值组合可以组成i 那么sum-i-i就是答案。如何判断是否对于一个数i用这些硬币可以凑出来,用背包判就可以了,注意是01背包。
#include <algorithm> #include <iostream> #include <cstring> #include <cstdlib> #include <string> #include <cctype> #include <vector> #include <cstdio> #include <cmath> #include <queue> #include <stack> #include <map> #include <set> #define maxn 55005 #define _ll __int64 #define ll long long #define INF 0x3f3f3f3f #define Mod 1<<40+10 #define pp pair<int,int> #define ull unsigned long long using namespace std; int v[115],dp[maxn],n,s; void solve() { memset(dp,0,sizeof(dp));dp[0]=1; for(int i=1;i<=n;i++) for(int j=s/2;j>=0;j--) dp[j+v[i]]+=dp[j]; for(int i=s/2;i>=0;i--) if(dp[i]) { printf("%d\n",s-i*2); return ; } } int main() { int T;scanf("%d",&T); while(T--) { scanf("%d",&n);s=0; for(int i=1;i<=n;i++) { scanf("%d",v+i); s+=v[i]; } solve(); } return 0; }
时间: 2024-10-11 11:08:35