1254: [DP地狱训练]石子归并
时间限制: 1 Sec 内存限制: 64 MB
提交: 694 解决: 295
[提交][状态][讨论版]题目描述
有一堆石头质量分别为W1,W2,…,Wn.(Wi≤ 10000),将石头合并为两堆,使两堆质量的差最小。输入
输入第一行只有一个整数n(1≤n≤50),表示有n堆石子。接下去的n行,为每堆石子质量。输出
输出只有一行,该行只有一个整数,表示最小的质量差.样例输入
5 5 8 13 27 14
样例输出
3
判定性dp,见代码。
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 #include <iostream> 2 #include <algorithm> 3 #include <cstdio> 4 #include <cstring> 5 #include <cstdlib> 6 #include <vector> 7 8 using namespace std; 9 10 /* 11 f[i][j] = 前i个石子使得|A| - |B| = j是否能够实现 12 f[i][j] = or { f[i - 1][j + w[i]], f[i - 1][j - w[i]] } 13 */ 14 #define N (50 * 10000 + 100) 15 int n, w, p; 16 bool f[2][N * 2]; 17 18 19 20 int main(){ 21 f[0][N + 0] = 1; 22 scanf("%d", &n); 23 for(int i = 1 ; i <= n ; i ++){ 24 p = !p; 25 scanf("%d", &w); 26 for(int j = -N ; j <= N ; j ++){ 27 f[p][N + j] = f[!p][N + j + w] | f[!p][N + j - w]; 28 } 29 } 30 for(int i = 0 ; i <= N ; i ++){ 31 if(f[p][N + i] | f[p][N - i]){ 32 printf("%d\n", i); 33 break; 34 } 35 } 36 }