ural
思路:
一直TLE,看了宇神博客惊奇的发现,宏定义的max函数给AC了;本题是把两堆西瓜平均分使差值最小,有意思的是这个题的价值和重量是一个概念(相对于普通的01背包),之后就可已01背包解决了;
#include <cstdio> #include <cstring> #define max(a, b) (a > b? a: b) //真要写成这样才给过,自己写的函数快 int dp[100010], a[30]; int main() { int n; while(scanf("%d", &n) != EOF) { int sum = 0; memset(dp, 0, sizeof(dp)); for(int i = 0; i < n; i++) { scanf("%d", &a[i]); sum += a[i]; } int v = sum; sum >>= 1; for(int i = 0; i < n; i++) { for(int j = sum; j >= a[i]; j--) { dp[j] = max(dp[j], dp[j - a[i]] + a[i]); } } printf("%d\n", v - dp[sum]*2); } return 0; } 思路:加一个剪枝就过了,n比较小,dfs应该才是正解,毕竟估计一下复杂度,1500*10000*20,;
#include <cstdio> #include <cstring> #define max(a, b) (a > b? a: b) int dp[100010], a[30]; int n, sum = 0, v, maxn; void dfs(int x, int val) { if(val > sum) return; if( x == n) { maxn = max(val, maxn); return; } dfs(x + 1, val + a[x + 1]); dfs(x + 1, val); return ; } int main() { while(scanf("%d", &n) != EOF) { maxn = 0; sum = 0; memset(dp, 0, sizeof(dp)); for(int i = 1; i <= n; i++) { scanf("%d", &a[i]); sum += a[i]; } v = sum; sum >>= 1; dfs(0, 0); printf("%d\n", v - maxn*2); } return 0; }