Pagini recente » Cod sursa (job #3195043) | Cod sursa (job #1181900) | Cod sursa (job #185174) | Cod sursa (job #2641188) | Cod sursa (job #2125994)
#include <algorithm>
#include <fstream>
#include <vector>
using namespace std;
struct Solution
{
int total_weight;
vector<int> weights;
};
struct Trace
{
int weight;
int count;
};
constexpr Trace kEmptyTrace = {0, 0};
constexpr int kMaxWeight = 75000;
constexpr int kInf = (1 << 25);
vector<int> GetPieceSizes(int count)
{
vector<int> pieces;
int power = 1;
while (power <= count) {
pieces.push_back(power);
count -= power;
power <<= 1;
}
if (count > 0) {
pieces.push_back(count);
}
return pieces;
}
void AddObject(int weight, int count, vector<int> &cost, vector<Trace> &trace)
{
auto total_weight = weight * count;
auto start = cost.size() - total_weight - 1;
for (int i = start; i >= 0; --i) {
if (cost[i] >= kInf) {
continue;
}
auto new_weight = i + total_weight;
auto new_cost = cost[i] + count;
if (new_cost < cost[new_weight]) {
cost[new_weight] = new_cost;
trace[new_weight].weight = weight;
trace[new_weight].count = count;
}
}
}
void FindCosts(const vector<int> &obj, vector<int> &cost, vector<Trace> &trace)
{
fill(cost.begin(), cost.end(), kInf);
cost[0] = 0;
fill(trace.begin(), trace.end(), kEmptyTrace);
for (size_t i = 1; i < obj.size(); ++i) {
if (obj[i] <= 0) {
continue;
}
auto sizes = GetPieceSizes(obj[i]);
for (const auto &size : sizes) {
AddObject(i, size, cost, trace);
}
}
}
vector<int> Reconstruct(const vector<Trace> &trace, int weight)
{
vector<int> weights;
while (weight > 0) {
auto count = trace[weight].count;
auto added = trace[weight].weight;
for (int i = 0; i < count; ++i) {
weights.push_back(added);
}
weight -= count * added;
}
return weights;
}
Solution Solve(const vector<int> &obj, int cap)
{
vector<int> cost(cap + 1);
vector<Trace> trace(cap + 1);
FindCosts(obj, cost, trace);
auto max_weight = cap;
while (max_weight > 0 && cost[max_weight] >= kInf) {
max_weight -= 1;
}
vector<int> weights(cost[max_weight], 0);
return {max_weight, weights};
// auto weights = Reconstruct(trace, max_weight);
// return {max_weight, weights};
}
int main()
{
ifstream fin("ghiozdan.in");
ofstream fout("ghiozdan.out");
int n, capacity;
fin >> n >> capacity;
vector<int> objects(kMaxWeight + 1, 0);
for (int i = 0; i < n; ++i) {
int weight;
fin >> weight;
objects[weight] += 1;
}
auto res = Solve(objects, capacity);
fout << res.total_weight << " " << res.weights.size() << "\n";
for (const auto &weight : res.weights) {
fout << weight << "\n";
}
return 0;
}