题意:特殊的背包问题, 背包的容量是v, 有两张可以选择的物品,体积1的物品有x件, 体积2的物品有y件, 体积相同的物品的能力值并不相同, 问你该怎么装, 使的总能力值最大。
思路:贪心的思路,将体积1和2的物品分别按照能力值大小排序, 首先将体积是2的物品按序装到背包, 然后将体积是1的物品按序装到背包, 如果背包满了, 还有体积是1的剩余, 则将体积1的两个组合或者1个(只剩一个了)从后往前替换体积为2的物体(能力值要比体积为2的大才替换)
代码:
#include <stdio.h>
#include <algorithm>
#include <vector>
using namespace std;
const int MAXN = 100005;
struct Vehicle
{
int id, cap;
bool operator<(const Vehicle &v) const
{
return cap > v.cap;
}
Vehicle(){}
Vehicle(int x, int y) : id(x), cap(y){}
};
int cap[MAXN];
vector<Vehicle> veh1;
vector<Vehicle> veh2;
int main()
{
#ifdef _LOCAL
freopen("F://input.txt", "r", stdin);
#endif
int n, v;
scanf("%d%d", &n, &v);
for(int i = 1; i <= n; ++i)
{
int a, b;
scanf("%d%d", &a, &b);
cap[i] = b;
if(a == 1)
veh1.push_back(Vehicle(i, b));
else
veh2.push_back(Vehicle(i, b));
}
sort(veh1.begin(), veh1.end());
sort(veh2.begin(), veh2.end());
vector<int> ans;
int totalCap = 0;
for(int i = 0; i < veh2.size() && v >= 2; ++i, v -= 2)
{
totalCap += veh2[i].cap;
ans.push_back(veh2[i].id);
}
int endFlag = ans.size() - 1;
int startFlag = 0;
for( ; startFlag < veh1.size() && v; ++startFlag, --v)
{
ans.push_back(veh1[startFlag].id);
totalCap += veh1[startFlag].cap;
}
for(int i = endFlag, j = startFlag; i >= 0 && j < veh1.size(); --i, ++j)
{
if(j + 1 < veh1.size())
{
if(cap[ans[i]] >= veh1[j].cap + veh1[j + 1].cap)
break;
totalCap = totalCap - cap[ans[i]] + veh1[j].cap + veh1[j + 1].cap;
ans[i] = veh1[j].id;
ans.push_back(veh1[j + 1].id);
j = j + 1;
}
else if(cap[ans[i]] < veh1[j].cap)
{
totalCap = totalCap - cap[ans[i]] + veh1[j].cap;
ans[i] = veh1[j].id;
}
}
printf("%d\n", totalCap);
for(int i = 0; i < ans.size(); ++i)
printf("%d ", ans[i]);
return 0;
}