问题名称都是自己起的,存在不严谨之处请斧正。
背包问题 :
version1:朴素版本
#include<cstdio>
/*
测试用例
5 8
3 5 1 2 2
4 5 2 1 3
*/
const int maxn = 30;
int n, V, maxValue = 0;//物品数量,背包容量,最大价值
int w[maxn], c[maxn];//每件物品的重量和价值
void DFS(int index,int sumW,int sumC)
{
if(index==n)
{
if(sumW<=V && sumC>maxValue)
maxValue = sumC;
return;
}
//不选第index件物品,当前背包内装载物品的重量与价值不变
DFS(index + 1, sumW, sumC);
//选第index件物品,当前背包内装载物品的重量与价值更新
DFS(index + 1, sumW + w[index], sumC + c[index]);
}
int main()
{
scanf("%d%d", &n, &V);
for (int i = 0; i < n; i++)
scanf("%d", &w[i]);
for (int i = 0; i < n; i++)
scanf("%d", &c[i]);
DFS(0, 0, 0);
printf("%d", maxValue);
getchar();
}
version2:剪枝版本
#include<cstdio>
/*
测试用例
5 8
3 5 1 2 2
4 5 2 1 3
*/
const int maxn = 30;
int n, V, maxValue = 0;//物品数量,背包容量,最大价值
int w[maxn], c[maxn];//每件物品的重量和价值
void DFS(int index,int sumW,int sumC)
{
if(index==n)
return;
//不选第index件物品,当前背包内装载物品的重量与价值不变
DFS(index + 1, sumW, sumC);
//剪枝:考虑仅当当前重量小于背包容量时进入
if(sumW+w[index]<=V)
{
if(sumC+c[index]>maxValue)
maxValue = sumC + c[index];
//选第index件物品,当前背包内装载物品的重量与价值更新
DFS(index + 1, sumW + w[index], sumC + c[index]);
}
}
int main()
{
scanf("%d%d", &n, &V);
for (int i = 0; i < n; i++)
scanf("%d", &w[i]);
for (int i = 0; i < n; i++)
scanf("%d", &c[i]);
DFS(0, 0, 0);
printf("%d", maxValue);
getchar();
}
最优子序列问题:
#include<cstdio>
#include<vector>
using namespace std;//使用vector要声明命名空间std
/*
测试用例
4 6 2
2 3 3 4
*/
const int maxn = 10;
int n, k, x, maxSumSqu = -1, A[maxn];
vector<int> temp, ans;
void DFS(int index, int nowK, int sum, int sumSqu)
{
if(nowK==k&&sum==x)
{
if(sumSqu>maxSumSqu)
{
maxSumSqu = sumSqu;
ans = temp;
}
return;
}
if(index==n||nowK>k||sum>x)
return;
//选择A[index],推入temp,改变相应的值
temp.push_back(A[index]);
DFS(index + 1, nowK + 1, sum + A[index],
sumSqu + A[index] * A[index]);
//弹出A[index],也代表不选择它
temp.pop_back();
//不选A[index],相应的值不变
DFS(index + 1, nowK, sum, sumSqu);
}
int main()
{
scanf("%d%d%d", &n, &x, &k);
for (int i = 0; i < n; i++)
scanf("%d", &A[i]);
DFS(0, 0, 0, 0);
for(int i:ans)
printf("%d ", i);
getchar();
}
重复最优子序列问题:
#include<cstdio>
#include<vector>
using namespace std;//使用vector要声明命名空间std
/*
测试用例
3 17 5
1 4 7
*/
const int maxn = 10;
int n, k, x, maxSumSqu = -1, A[maxn];
vector<int> temp, ans;
void DFS(int index, int nowK, int sum, int sumSqu)
{
if(nowK==k&&sum==x)
{
if(sumSqu>maxSumSqu)
{
maxSumSqu = sumSqu;
ans = temp;
}
return;
}
if(index==n||nowK>k||sum>x)
return;
//再一次选择A[index],推入temp,改变相应的值
temp.push_back(A[index]);
//注意DFS()第一个参数改为了index,而非index+1
DFS(index, nowK + 1, sum + A[index],
sumSqu + A[index] * A[index]);
//弹出A[index],也代表不选择它
temp.pop_back();
//不选A[index],相应的值不变
DFS(index + 1, nowK, sum, sumSqu);
}
int main()
{
scanf("%d%d%d", &n, &x, &k);
for (int i = 0; i < n; i++)
scanf("%d", &A[i]);
DFS(0, 0, 0, 0);
for(int i:ans)
printf("%d ", i);
getchar();
}