1 、有n件物品,每件重量为w[i],价值c[i]。有一个背包容量为V,在不超过V的前提下向书包中放入物品,使书包中物品总价值最大,求最大值。
#include<iostream>
using namespace std;
const int maxn = 20;
int w[maxn], c[maxn], v,n,maxC=0;//w:物品重量 c:对应物品的价值 v背包容量 n物品种类总数 maxC当前背包中物品总价值。
void DFS(int index, int sumW, int sumC) {
if (index == n) {//已经完成对n件物品的选择 (深度遍历中的死胡同)
if (sumW<=v&&maxC < sumC)//没有超过书包容量的情况下,如果书包内物品总价值比最大价值大,则更新最大值
maxC = sumC;
return;
}
DFS(index + 1, sumW, sumC);//不选择第index件物品
DFS(index + 1, sumW + w[index], sumC + c[index]);//选择第index件物品
}
int main() {
cin >> n >> v;
for (int i = 0; i < n; i++) {
cin >> w[i];
}
for (int i = 0; i < n; i++) {
cin >> c[i];
}
DFS(0, 0, 0);
cout << maxC;
system("pause");
return 0;
}
上面算法复杂度为o(),不是很优秀。下面进行改进。在上述代码中,在对n件物品选择完后再更新最大值,忽略了总重量不大于V这个特点。可以在遍历过程中进行判断是否大于V。
void DFS(int index, int sumW, int sumC) {
if (index == n) {//已经完成对n件物品的选择 (深度遍历中的死胡同)
return;
}
DFS(index + 1, sumW, sumC);//不选择第index件物品
if (sumW + w[index] <= v) {
if (sumC + c[index] > maxC)
maxC = sumC + c[index];
DFS(index + 1, sumW + w[index], sumC + c[index]);//选择第index件物品
}
}
2、给定N个正整数,从中选择K个数,使得这K个数之和为给定的数X,如果有多种方案则取平方和大的方案。返回合适的方案。
void DFS(int index, int nowK, int sum, int sumSquK) {
if (nowK == K&&sum == X) {//找到K个数且合为X
if (sumSquK > maxSqu) {//如果平方和比当前更大
res = temp; //更新方案
maxSqu = sumSquK; //更新平方和
}
return;
}
if (index == n || nowK > K|| sum>X) return;
DFS(index + 1, nowK,sum, sumSquK);//不选择第index件物品
temp.push_back(nums[index]);
DFS(index, nowK + 1, sum+nums[index],sumSquK + pow(nums[index], 2));
temp.pop_back();
}