“背包题目”的基本描述是:有一个背包,能盛放的物品总体积为T,设有N件物品,其
体积
分别为w1,w2,…,wn,希看从N件物品中选择若干物品,所选物品的
体积
之和恰能放进该背包,即所选物品的
体积
之和即是T。
有两种解法
递归和贪心算法,
不过递归只能求出一种解,而贪心算法可以求出所有解。
1.递归算法
#include <iostream>
using namespacestd;
const int N =5;//物品数量
const int S =10;//能盛放的物品总重量
int w[N+1] ={1, 8, 4, 3, 5, 2};
int knap(int s, int n)
{
if(s == 0)
{
return 1;
}
if(s<0 ||(n<1))
{
return 0;
}
//第n个物品入选
if(knap(s-w[n], n-1))
{
cout << w[n]<< " ";
return 1;
}
//第n个物品没入选
return knap(s, n-1);
}
int main(intargc, char *argv[])
{
if(knap(S, N))
{
cout << endl<< "OK"<< endl;
}
else
{
cout << "NO"<< endl;
}
return 0;
}
2.贪心算法
#include <iostream>
#include <vector>
using namespace std;
int main()
{
vector<int>w, flag;
int T, counter=0, total1, item;
cout << "请输入背包体积:";
cin >> T;
cout << "背包体积为:"<< T <<endl;
cout << "请输入物体数量:";
cin>> total1;
cout<< "总共"<< total1<< "件物品"<< endl<< "请输入每件物品的体积:\n";
for(int i=0;i<total1; i++)
{
cin>> item;
w.push_back(item);
flag.push_back(0);
}
cout<< "\n物品的体积如下所示:"<< endl;
for (int i=0; i<total1; i++)
cout << w[i]<< "\t";
cout << endl;
int count = 0;
int all_count = 1;
for (int i=0; i<total1; i++)
{
all_count *= 2;//all_count记录可能解的个数
}
while (1)
{
for (int i=0; i<total1; i++) //列举所有flag数组可能
{
if ( 0 == flag[i] )
{
flag[i] = 1;
continue;
}
else
{
flag[i] = 0;
break;
}
}
int temp = 0;
for (int i=0; i!=total1; i++) // 按标记计算所有选中物品重量和
{
if ( 1 == flag[i] )
temp += w[i];
}
if ( temp == T ) // 满足背包重量就打印
{
counter++;
cout << "解"<< counter<< "为"<< endl;
for (int i=0; i<total1; i++)
{
if ( 1 == flag[i] )
cout << w[i]<< "\t";
}
cout <<endl;
}
// 如果遍历了所有情况就跳出循环
count++;
if (count == all_count)
break;
}
return 0;
}