用01背包解决石子归并问题
来源:互联网 发布:wlk魔兽数据库 多玩 编辑:程序博客网 时间:2024/06/06 16:32
http://blog.csdn.net/w397090770/article/details/8028945
题目:有一堆石头质量分别为W1,W2,W3...WN.(W<=100000)现在需要你将石头合并为两堆,使两堆质量的差为最小。
这道题目可以用01背包问题来解决。即求出和最接近sum/2的一个子集令f(i, j)表示前i个元素中和最接近j的子集的和(有点绕),则有: f(i, j) = max( f(i-1, j), f(i-1, j-a[i])+a[i] ) ,其中a数组是用来存储所有石头的质量的。
源码如下:
以下是参考代码:
#define N1 8int W1;int* Table[N1+1];int Weight[N1+1]={-1,3,41,25,6,2,3,7,10};int* Path[N1+1];void tet(){int sum=0;for(int i=1;i<N1+1;i++){sum+=Weight[i];}cout<<"sum:"<<sum<<endl;W1=sum>>1;for(int i=0;i<N1+1;i++){Table[i]=(int*)malloc(sizeof(int)*(W1+1));Path[i]=(int*)malloc(sizeof(int)*(W1+1));memset(Table[i],0,sizeof(int)*(W1+1));memset(Path[i],0,sizeof(int)*(W1+1));}for(int i=0;i<N1+1;i++){for(int j=0;j<W1+1;j++){Table[i][j]=-1;Path[i][j]=0;}}for(int i=0;i<N1+1;i++)Table[i][0]=0;for(int j=0;j<W1+1;j++)Table[0][j]=0;}int Calculate(){tet();for(int i=1;i<N1+1;++i){for(int j=1;j<W1+1;j++){Table[i][j]=Table[i-1][j];if(j>=Weight[i]){int t1=Table[i-1][j];int t2=Table[i-1][j-Weight[i]]+Weight[i];if(t2>t1)Path[i][j]=1;Table[i][j]=t2>t1?t2:t1;}}}int i=N1,j=W1;while(i>0&&j>0){if(Path[i][j]==1){j-=Weight[i];cout<<Weight[i]<<" ";}i--;}cout<<endl;return Table[N1][W1];}int main(){//tet();cout<<Calculate();return 0;}
也可以参考原文的代码:
#include <stdio.h>#define N 5// Author: 397090770// E-mail: wyphao.2007@163.com// 转载请注明。int do_(int *arr, int m){if(arr == NULL){return;}int i = 0, j = 0;int c[N + 1][100];//这个相当于上面的f(i,j)for(i = 0;i < N + 1; i++)//初始化 for(j = 0; j < 100; j++) c[i][j]=0; for(i = 1; i < N + 1; i++) for(j = 1; j< m + 1; j++){ if(arr[i - 1] <= j){ if(arr[i - 1] + c[i-1][j-arr[i - 1]] > c[i-1][j]) c[i][j] = arr[i - 1] + c[i-1][j-arr[i - 1]]; else c[i][j] = c[i-1][j]; }else c[i][j] = c[i-1][j]; } //printf("%d\n", c[N][m]);return c[N][m];//最后一个就是最优值}int main(){int arr[N] = {/*1, 5, 7, 8, 9, 6, 3, 11, 20, 17*/5, 8, 13, 27, 14};int sum = 0;int i = 0;for(i = 0; i < N; i++){sum += arr[i];}int result = do_(arr, sum / 2);printf("%d\n", sum - 2 * result);return 0;}
- 用01背包解决石子归并问题
- 用01背包解决石子归并问题
- 石子归并问题
- 石子归并问题
- GarsiaWachs算法:石子归并问题
- 石子归并问题(区间dp)
- 石子归并问题(codevs 1048)
- 【区间型DP】石子归并问题
- 区间DP入门之 石子归并问题
- 石子归并
- 石子归并
- 石子归并
- 石子归并
- 石子归并
- 石子归并
- 石子归并
- 石子归并
- 石子归并
- SQLSERVER2008 18456错误
- Web.config文件例子详解
- Android Looper和Handler
- zoj 1586 QS Network
- sqlserver里存储过程执行时间差的打印
- 用01背包解决石子归并问题
- 图像特征特点及其常用的特征提取与匹配方法
- PHP操作文件,目录
- EM(EXCEPTION MAXIMATION)
- wince 常见问题
- fibonacci数列
- 项目经验----触发器要谨慎使用(转自娟姐)
- 博客博客,我回来了
- linux env 命令