给出一个序列,枚举这个序列的所有子序列(可以不连续)
例如序列{1,2,3}来说
他的所有子序列为{1}、{2}、{3}、{1,2}、{1,3}、{2,3}、{1,2,3}
枚举所有子序列的目的很明显:可以从中选择一个“最优”子序列,使它的某个特征是所有子序列中最优的,
如果有需要,还可以把这个最优子序列保存下来。
显然这个问题也等价于枚举从N个整数中选择K个数的所有方案
给定N个整数,从中选择K个数,使的这K个数之和恰好等于一个给定的整数X
如果有多种方案,选择他们元素平方和最大的一个,保证方案唯一
从4个整数{2,3,4,4}选择2个数,
使他们的和为6
显然有{2,4}{3,3,}两个方案,其中平方和最大的方案是{2,4}
与之前的问题类似
我们需要记录当前处理的整数编号index
由于恰好选择K个数,因此需要一个参数nowK来记录当前已经选择的数的个数
另外,还需要参数sum来记录整数之和
sumSqu记录当前已选平方和
此处,讲解如何保存最优方案(平方和最大的方案)
1.temp数组,用来存放当前已经选择的整数,
这样当试图进入“index号数”这条分支时,就可以把A[index]放入temp中
而当这条分支结束时,就把他从temp中取出,使他不会影响“不选index号数”这条分支。
2.如果,在某个时候,发现当前已经选择了k个数,且这k个数之和恰好为x时,就去判断平方和是否比已有的最大平方和maxSumSqu还要大:如果确实更大,那么说找到了更优的方案,把temp赋值给存放最优方案的数组ans
3.这样,当所有方案都枚举完毕,ans存放的就是最优方案,maxSumSqu存放的就是对应的最优值
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>maxSqu){
maxSumSqu=sumSqu;
ans=temp;
}
return;
}
if(index == x || nowK>k||sum>x)return;
temp.push(A[index]);
dfs(index+1,nowK+1,sum+A[index],sumSqu+A[index]*A[index]);
temp.pop_back();
dfs(index+1,nowK,sum,sumSqu);
}
//如果每个整数可以被选择多次,就当选择了index号数,不应当直接进入index+1号数的处理
//显然,还应该继续选择index号数,直到某个时候不再选择index号数,就会通过“不选index号数”这条分支进入index+1号数的处理
//将选择“index号数”的这条分支代码 dfs(index+1,nowK+1,sum+A[index],sumSqu+A[index]*A[index]);
//修改为
dfs(index,nowK+1,sum+A[index],sumSqu+A[index]*A[index]);
//背包问题
//有n件物品,每件物品的重量为w[i],价值为c[i],现在需要选出若干物品来放入一个容量为v的背包中
//使的在选入背包的物品重量和不超过容量v的前提下,让背包中物品的价值和最大,求最大价值(1<=n<=20)
//5 8
//3 5 1 2 2
//4 5 2 1 3
//5 8
//3 5 1 2 2
//4 5 2 1 3
//10
#include <iostream>
#include <cstdio>
using namespace std;
int n,v;
int w[30],c[30];
int maxValue=0;
void dfs(int index,int sumW,int sumC){
if(index==n){
return;
}
if(sumW<=v&&sumC>maxValue){
maxValue=sumC;
}
//if(index>n||sumW>v)return;
dfs(index+1,sumW,sumC);//不选第index件物品
dfs(index+1,sumW+w[index],sumC+c[index]);//选第index件物品
}
int main()
{
scanf("%d%d",&n,&v);//5 8 //5件物品,背包容量为8
for(int i=0;i<n;i++){
scanf("%d",&w[i]);//3 5 1 2 2//每件物品的重量
}
for(int i=0;i<n;i++){
scanf("%d",&c[i]);//4 5 2 1 4//每件物品的价值
}
dfs(0,0,0);//第0件物品---w[0]---c[0],初始化为第0件物品,当前总重量和总价值均为0
printf("%d\n",maxValue);
return 0;
}