标签:style blog class c code ext
5
5 8 13 27 14
3
主要题意:
将一堆物品分为两堆,使得两堆的质量只差最小。
思路:
01背包问题。用zhiliang[]来表示所有西瓜的质量将所有的西瓜的质量总和sum的一半v=sum/2来当做一个背包的容量,接下来的任务就是向这个容量为v的背包里尽可能多的装西瓜。得到一个尽可能装满v的质量dp[v];所求结果的质量之差的最小值=(sum-dp[v])-dp[v];
用dp[j]来表示容量为j时候能装进去的最大质量。当j>zhiliang[i]时候,可以有装入该西瓜和不装入两种选择,选择一个结果较大的,dp[j]=max(dp[j],dp[j-zhiliang[i]]+zhiliang[i]);
这个题目用dfs写会比01背包写着会快好多。值得注意的是,sum将会是一个很大的数,最好用long long。注意dp初始赋值的时候的长度!!!!!
01背包AC代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34 |
#include<iostream> #include<stdio.h> #include<stdlib.h> #include<string.h> #include<algorithm> using
namespace std; #define Max(a,b) a>b?a:b int
zhiliang[21]; int
dp[100001]={0}; int
main() { int
n; long
long v,sum; while ( scanf ( "%d" ,&n)!=EOF) { sum=0; for ( int
i=0;i<n;i++) { scanf ( "%d" ,&zhiliang[i]); sum+=zhiliang[i]; } v=sum/2; fill(dp,dp+v+1,0); for ( int
i=0;i<n;i++) { for ( int
j=v;j>=zhiliang[i];j--) { dp[j]=Max(dp[j],dp[j-zhiliang[i]]+zhiliang[i]); } } printf ( "%d\n" ,sum-2*dp[v]); } system ( "pause" ); return
0; } |
dfs的AC代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32 |
#include <stdio.h> #define max(a,b) a>b?a:b int
V,ans,n,w[21],sum[21]; void
dfs( int
i, int
cnt) { if (i == 0) { ans = max(ans,cnt); return
; } if (ans == V || cnt+sum[i] <= ans) //cut return
; if (cnt+w[i] <= V) dfs(i-1,cnt+w[i]); dfs(i-1,cnt); } int
main() { while (~ scanf ( "%d" ,&n)) { ans = 0; for ( int
i=1;i<=n;i++) { scanf ( "%d" ,&w[i]); sum[i] = sum[i-1] + w[i]; } V = sum[n]/2; dfs(n,0); printf ( "%d\n" ,sum[n]-2*ans); } return
0; } |
动态规划(5)——01背包问题(NYOJ325zb的生日),布布扣,bubuko.com
标签:style blog class c code ext
原文地址:http://www.cnblogs.com/xueniwawa/p/3738596.html