Pagini recente » Cod sursa (job #1052004) | Cod sursa (job #2585170) | Cod sursa (job #1694033) | Cod sursa (job #2584367) | Cod sursa (job #502553)
Cod sursa(job #502553)
#include <cstdio>
#include <vector>
#include <deque>
using namespace std;
const int MAX_WEIGHT = 210;
const int MAX_CAPACITY = 75010;
const int INFINITY = 100000;
int totalCapacity, maxCapacity;
int weightsCount[MAX_WEIGHT];
int dp[2][MAX_CAPACITY];
vector <int> solution;
void read() {
freopen("ghiozdan.in", "r", stdin);
int noObjects;
scanf("%d %d", &noObjects, &totalCapacity);
for (int i = 1; i <= noObjects; ++i) {
int weight;
scanf("%d", &weight);
++weightsCount[weight];
}
}
void doDP(int minWeight, int maxWeight, int desiredWeight) {
int now = minWeight&1, last = now^1;
dp[last][0] = 0;
for (int i = 1; i <= desiredWeight; ++i)
dp[last][i] = INFINITY;
for (int i = minWeight; i <= maxWeight; ++i, now ^=1, last ^= 1)
for (int j = 0; j < i; ++j) {
deque <int> prevLine;
for (int k = j; k <= desiredWeight; k += i) {
while (prevLine.size() > 0 && dp[last][prevLine.back()]
+ (k-prevLine.back()) / i >= dp[last][k])
prevLine.pop_back();
prevLine.push_back(k);
while (prevLine.front() < k-i*weightsCount[i])
prevLine.pop_front();
dp[now][k] = dp[last][prevLine.front()] + (k-prevLine.front()) / i;
}
}
}
void findSolution(int minWeight, int maxWeight, int desiredWeight,
int noObjects) {
if (minWeight == maxWeight) {
for (int i = minWeight; i <= desiredWeight; i += minWeight)
solution.push_back(minWeight);
} else {
int middleWeight = (minWeight+maxWeight) / 2;
doDP(minWeight, middleWeight, desiredWeight);
int tmp[MAX_CAPACITY];
for (int i = 0; i <= desiredWeight; ++i)
tmp[i] = dp[middleWeight&1][i];
doDP(middleWeight+1, maxWeight, desiredWeight);
for (int weightLeft = 0; weightLeft <= desiredWeight; ++weightLeft) {
int weightRight = desiredWeight - weightLeft;
int noObjectsLeft = tmp[weightLeft];
int noObjectsRight = dp[maxWeight&1][weightRight];
if (noObjectsLeft + noObjectsRight == noObjects) {
if (weightLeft > 0)
findSolution(minWeight, middleWeight, weightLeft, noObjectsLeft);
if (weightRight > 0)
findSolution(middleWeight+1, maxWeight, weightRight, noObjectsRight);
break;
}
}
}
}
void solve() {
doDP(1, MAX_WEIGHT-1, totalCapacity);
maxCapacity = totalCapacity;
while (dp[(MAX_WEIGHT-1)&1][maxCapacity] == INFINITY && maxCapacity >= 0)
--maxCapacity;
findSolution(1, MAX_WEIGHT-1, maxCapacity, dp[(MAX_WEIGHT-1)&1][maxCapacity]);
}
void write() {
freopen("ghiozdan.out", "w", stdout);
printf("%d %d\n", maxCapacity, solution.size());
for (size_t i = 0; i < solution.size(); ++i)
printf("%d\n", solution[i]);
}
int main() {
read();
solve();
write();
return 0;
}