京东2016实习生招聘c++开发工程师在线考试-买糖果

题目:


代码如下:

#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)结合使用是该类问题的通解(针对不同问题可能要考虑重复问题).

以上均是个人理解,不足之处可发邮件讨论。



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值