1.01背包问题-回溯法
#include<bits/stdc++.h>
using namespace std;
int c, n, cw, cv, bestv;
struct Object {
int w;
int v;
double d;
}Q[100];
bool cmp(Object a, Object b) {
if (a.d >= b.d) return true;
else return false;
}
int Bound(int i)
{
int cleft = c - cw;
int b = cv;
while (i < n && Q[i].w <= cleft) {
cleft -= Q[i].w;
b += Q[i].v;
i++;
}
if (i < n) b += 1.0 * cleft * Q[i].v / Q[i].w;
return b;
}
void backtrack(int i)
{
if (i + 1 > n) { bestv = cv; return; }
if (cw + Q[i].w <= c) {
cw += Q[i].w;
cv += Q[i].v;
backtrack(i + 1);
cw -= Q[i].w;
cv -= Q[i].v;
}
if (Bound(i + 1) > bestv)
backtrack(i + 1);
}
int main()
{
cout << "请输入背包容量和数量";
cin >> c >> n;
for (int i = 0; i < n; i++) {
cout << "请输入第" << i + 1 << "个物品的重量和价值";
cin >> Q[i].w >> Q[i].v;
Q[i].d = 1.0 * Q[i].v / Q[i].w;
}
sort(Q, Q + n, cmp);
cw = 0;
cv = 0;
backtrack(0);
cout << "背包能装下的最大价值为" << bestv << endl;
return 0;
}
2.装载问题
#include<iostream>
using namespace std;
int n, c, w[100], x[100], r, cw, bestw, bestx[100];
void backtrack(int t)
{
if (t > n) {
if (cw > bestw)
{
for (int i = 1; i <= n; i++)
bestx[i] = x[i];
bestw = cw;
}
return;
}
r -= w[t];
if (cw + w[t] <= c)
{
x[t] = 1;
cw += w[t];
backtrack(t + 1);
cw -= w[t];
}
if (cw + r > bestw)
{
x[t] = 0;
backtrack(t + 1);
}
r += w[t];
}
int main()
{
cout << "请输入集装箱数量:";
cin >> n;
cout << "请输入轮船载重量:";
cin >> c;
r = 0;
cout << "请依次输入每个集装箱的重量:";
for (int i = 1; i <= n; i++) {
cin >> w[i];
r += w[i];
}
cw = 0;
bestw = 0;
backtrack(1);
cout << "轮船能装载的最大重量为:" << bestw << endl;
cout << "选择的集装箱编号为:";
for (int i = 1; i <= n; i++) {
if (bestx[i] == 1) {
cout << i << " ";
}
}
cout << endl;
return 0;
}
3.二分查找
#include<iostream>
using namespace std;
// 二分查找函数,返回目标元素第一次出现的位置
int binarySearch(int a[], int x, int n)
{
int left = 0;
int right = n - 1;
int result = -1;
while (left <= right)
{
int mid = (right + left) / 2;
if (x == a[mid])
{
result = mid;
// 继续向左查找,看是否有更早出现的目标元素
right = mid - 1;
}
else if (x > a[mid])
left = mid + 1;
else
right = mid - 1;
}
return result;
}
int main()
{
int n, c1[105], c2[105], m;
cout << "请输入n和要访问的个数";
cin >> n >> m;
cout << "请输入" << n << "个数组元素:";
for (int i = 0; i < n; i++)
{
cin >> c1[i];
}
cout << "请输入" << m << "个要访问的整数:";
for (int i = 0; i < m; i++)
{
cin >> c2[i];
}
for (int i = 0; i < m; i++)
{
cout << binarySearch(c1, c2[i], n) << " ";
}
return 0;
}
4.01背包-动态规划
#include <iostream>
#include <algorithm>
using namespace std;
int w[50], v[50], p[50][50];
void knapsack(int c, int n) {
int jMax = min(w[n] - 1, c);
for (int j = 0; j <= jMax; j++)
p[n][j] = 0;
for (int j = w[n]; j <= c; j++)
p[n][j] = v[n];
for (int i = n - 1; i >= 1; i--) {
jMax = min(w[i] - 1, c);
for (int j = 0; j <= jMax; j++)
p[i][j] = p[i + 1][j];
for (int j = w[i]; j <= c; j++)
p[i][j] = max(p[i + 1][j], p[i + 1][j - w[i]] + v[i]);
}
p[1][c] = p[2][c];
if (c >= w[1])
p[1][c] = max(p[1][c], p[2][c - w[1]] + v[1]);
}
int main() {
int n, c;
cout << "请输入物品数量 n 和背包容量 c: ";
cin >> n >> c;
cout << "请依次输入每个物品的重量和价值: " << endl;
for (int i = 1; i <= n; i++) {
cin >> w[i] >> v[i];
}
knapsack(c, n);
cout << "背包能装下的最大价值为: " << p[1][c] << endl;
return 0;
}