一个简单的0-1背包问题(2)
2012-11-30 15:43
295 查看
还是上次的问题,从N个数字(N较大)从取出随意m个数字(m不定)相加,得到最接近一个常数c的组合,原来用无穷列举的方法解出来,时间复杂度上为O(2^n),对于n比较大的情况,几乎为无解,重新设计了算法,用动态规划的方法实现,时间复杂度为nc,同样能够得到最优解,但是所花费的时间大大减小,唯一不爽的是,要求数组都是int类型,c也一样,如果是double类型的话,为了精度,需要开销的空间太大,我的老爷机没法继续实现,所以没有做double数组的算法,如果大家有兴趣,可以继续写下去
测试
void MyAlogorithms::Knapsack(int w[],int c,int n,int **f) { for (int y=0;y<=w[n-1];y++) f[n-1][y]=0; for (int y=w[n-1];y<c-1;y++) f[n-1][y]=w[n-1]; for (int i=n-2;i>=0;i--) { for (int y=0;y<=w[i];y++) f[i][y]=f[i+1][y]; for (int y=w[i];y<c-1;y++) f[i][y]=max(f[i+1][y],f[i+1][y-w[i]]+w[i]); } f[0][c-1]=f[1][c-1]; if (c>=w[0]) { f[0][c-1]=max(f[1][c-1],f[2][c-1-w[0]]+w[0]); } } void MyAlogorithms::Traceback(int **f,int w[],int c,int n,int x[]) { for (int i=0;i<n-1;i++) { if (f[i][c-1]==f[i+1][c-1]) { x[i]=0; } else { x[i]=1; c=c-w[i]; } } x[n-1]=(f[n-1][c-1])?1:0; }
测试
#include <iostream> #include <fstream> #include "MyAlgorithms.h" using namespace std; const int N=99; const int tarnum=412645; int main() { int i=0; int sum=0; int s ; ifstream in; in.open("shuzi.txt"); if (!in.is_open()) { cout<<"Can't open the file"; exit(EXIT_FAILURE); } in>>s[i]; while(in.good()) { i++; in>>s[i]; } MyAlogorithms ma; int **f=new int* ; for (int k=0;k<N;k++) { f[k]=new int[tarnum]; } int b ={0}; ma.Knapsack(s,tarnum,N,f); ma.Traceback(f,s,tarnum,N,b); for (int k=0;k<N;k++) { sum=sum+b[k]*s[k]; if (1==b[k]) { cout<<s[k]<<endl; } } cout<<sum<<endl; for(int k=0;k<N;k++) delete []f[k]; delete []f; system("Pause"); }
相关文章推荐
- 一个简单的背包问题
- 一个简单的0-1背包问题(1)
- 最简单的0-1背包问题c++代码实例及运行结果
- 一个简单的弹出对话框数据成员检验问题
- 一个简单问题三天解决的一个问题
- 一个简单的怪问题
- 写一个简单的常识问题以自警
- 一个简单的条件概率问题
- 一个简单的指针指向问题的讨论
- 今天同事问的一个简单的C51问题
- 一个简单的JS去空格问题
- NYOJ-106 简单背包问题
- iOS一个简单的设置圆角不引起性能问题的分类
- USACO Section 2.4 The Tamworth Two - 又犯2了..又把一个简单的问题整复杂了..
- 输入两个整数n和m,从数列1,2,3,……n中随意取几个数,使其和等于m。要求将所有的可能组合列出来。实际上就是一个背包问题
- 一个看似简单的问题(#if与#ifdef的区别)
- 一个简单的优化例子(锁问题)
- 一个简单的安卓小应用,开发步骤以及遇到的各种问题总结
- i++不是原子操作,看似简单,实则巨坑的一个线程同步的问题。synchronized 和 volatile
- 一个简单程序思考计算机里int数据的存储问题,兼论大端模式和小端模式