题目:
代码如下:
#include<iostream>
#include<string>
#include<vector>
#include<stack>
#include<fstream>
#include<map>
using namespace std;
class Solution {
public:
void dfs(vector<pair<int, pair<int, int>>>& candidates, int target, int &sum, int start){
int size = candidates.size();
for (int i = start; i < size; i++){
if (sum + candidates[i].second.first <= target){
temp.push_back(candidates[i]);
result.push_back(temp);
//凡是容量和小于V的都可加入
sum += candidates[i].second.first;
dfs(candidates, target, sum, i + 1);
temp.pop_back();
sum -= candidates[i].second.first;
}
}
}
vector<vector<pair<int, pair<int, int>>>>combinationSum2(vector<pair<int, pair<int, int>>>&candidates, int target) {
int size = candidates.size();
if (size == 0)return result;
int vtep = 0;//当前的容量
int start = 0;
temp.clear();
result.clear();
dfs(candidates, target, vtep, start);
return result;
}
vector<pair<int, pair<int, int>>>temp;
vector<vector<pair<int, pair<int, int>>>>result;
};
int main(){
int num;//糖果数量
int v;//车子容量
int test;
vector<pair<int, pair<int, int>>>sugle;
vector<vector<pair<int, pair<int, int>>>>re;
Solution s1;
ifstream fin("c:\\users\\dell\\desktop\\sugle_cin.txt");
int v_min, v_now, v_pre;
vector<int>mark;
int count = 0;
while (fin >> num){//每一个测试数据的开始
count = 0;
sugle.clear();
re.clear();
mark.clear();
fin >> v;
int t1, t2;
for (int i = 0; i < num; i++){
fin >> t1;
fin >> t2;
sugle.push_back(make_pair(++count, make_pair(t1, t2)));
}
re = s1.combinationSum2(sugle, v);
v_min = 0;
for (int i = 0; i < re.size(); i++){
v_now = 0;
for (int j = 0; j < re[i].size(); j++){
v_now += re[i][j].second.second;
}
if (v_min <= v_now){
if (v_min < v_now){
v_min = v_now;
mark.clear();
mark.push_back(i);
}
else{
mark.push_back(i);
}
}
}
cout << v_min << endl;
for (int i = 0; i < mark.size(); i++){
for (int j = 0; j < re[mark[i]].size(); j++)
cout << re[mark[i]][j].first << " ";
cout << endl;
}
}
return 0;
}
测试用例:
3 2
(1)1 2
(2)2 7
(3)1 3
4 4
(1)1 3
(2)2 2
(3)1 1
(4)2 2
5 6
(1)1 4
(2)2 4
(3)1 3
(3)2 2
(4)1 2
小括号只是为了标注行号,实际输入时是没有的;
输出结果:
算法综述:
1、vector<pair<int, pair<int, int>>>sugle容器保存所有的糖果的信息,例如(1)1 2,(2)2 7,(3)1 3等等;
2、采用深度优先搜索算法(DFS)将所有满足条件的组合(combination)都保存下来,因为每个测试例子的糖果编号都是从1开始到n,所以就没有必要考虑重复;相关内容可参考:https://leetcode.com/problems/combination-sum-ii/ ;
3、这类题目的本质是带约束条件的最大化问题,在本题中约束条件是在所有糖果的体积不超过车的容量的情况下使魔幻因子的总含量最高,相关的题目可以参考唯品会的爱情数字在线笔试题(如下图),本质都是一样(在不超过油漆总量的情况下,使得写出的最大数字),所以在这种约束条件下,DFS和回溯算法(backtracking)结合使用是该类问题的通解(针对不同问题可能要考虑重复问题).
以上均是个人理解,不足之处可发邮件讨论。