http://acm.zzuli.edu.cn/problem.php?id=1788
很有意思的一道题,当时周赛没写出来。。。。。
这是道背包题,思路想出来了就是裸的背包,想不出来那就是。。。不会做呗。
要求两份相差最小。
一开始想的用贪心做,错了。
那么说用背包咋做,先将所有的价值加起来sum,然后除以2得sum1,sum2=sum-sum1,那么现在abs(sum1-sum2)是不是就是最小了,
那后以sum1为背包的容量,物品的价值既是价值又是体积,然后直接用一维01背包就行了,就是将一个背包装的尽量满,那么另一个值sum-dp[sum1],就会和dp[sum1]越接近.
最后abs(2*dp[sum1]-sum),就为结果。
1 #include<stdio.h> 2 #include<algorithm> 3 #include<stdlib.h> 4 #include<iostream> 5 #include<string.h> 6 #include<math.h> 7 using namespace std; 8 int dp[50000]= {0}; 9 int main(void) 10 { 11 int a[200]; 12 int n,i,j,k,p,q; 13 scanf("%d",&n); 14 while(n--) 15 { 16 scanf("%d",&k); 17 int sum=0; 18 memset(dp,0,sizeof(dp)); 19 for(i=0; i<k; i++) 20 { 21 scanf("%d",&a[i]); 22 sum+=a[i]; 23 } 24 int mm=sum; 25 sum=sum/2; 26 for(i=1; i<=k; i++) 27 { 28 for(j=sum; j>=a[i-1]; j--) 29 { 30 dp[j]=max(dp[j],dp[j-a[i-1]]+a[i-1]); 31 } 32 } 33 mm-=dp[sum]; 34 printf("%d\n",abs(mm-dp[sum])); 35 } 36 return 0; 37 }
时间: 2024-12-16 10:38:24