Solving Programming Contest Problems: Selection, Review, and Time Management
Problem A: Minimal Operations through Recursive Decomposition
In this problem, we are tasked with finding the minimum number of operations to process a sequence. By analyzing small cases, a recursive pattern emerges. For a sequence of length $n$, the optimal number of steps $f(n)$ can be defined by the state of its half-length counterpart.
Consider a sequence $\{1, 2, \dots, n\}$. If we subtract $n/2$ from all elements greater than $n/2$, the sequence effectively mirrors its first half. Thus, the recurrence relation is $f(n) = f(\lfloor n/2 \rfloor) + 1$. This logarithmic behavior suggests that we are essentially counting the number of times we can bisect the range.
#include <iostream>
#include <vector>
using namespace std;
void compute_min_steps() {
long long target;
if (!(cin >> target)) return;
vector<long long> cache(target + 1);
cache[1] = 1;
for (int i = 1; i <= target; ++i) {
cache[i] = cache[i / 2] + 1;
}
cout << cache[target] << endl;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
compute_min_steps();
return 0;
}
Problem B: Optimizing Ratios under Budget Constraints
This problem involves maximizing the ratio $R = \frac{a}{a + b}$ given an initial budget $M$ and a cost $X$ per unit change. We can either increase the numerator $a$ or decresae the denominator $b$ (which also involves decreasing the total sum). The relationship $(1 - r)a - rb \geq 0$ indicates that the benefit of shifting units between $a$ and $b$ is linear.
Because of this linearity, the maximum value will occur at the boundaries of our possible operations. We should evaluate two primary scenarios:
- Allocating the entire budget to maximize $a$.
- Allocating the budget to minimize $b$ to its lowest possible non-negative value, then spending any remaining budget on $a$.
#include <iostream>
#include <algorithm>
#include <iomanip>
using namespace std;
void evaluate_review_score() {
long long budget, unit_cost, val_a, val_b;
cin >> budget >> unit_cost >> val_a >> val_b;
// Scenario 1: Maximize val_a
long long max_a = val_a + budget;
double score1 = (double)max_a / (max_a + val_b);
// Scenario 2: Minimize val_b first
long long reduction_b = budget / unit_cost;
long long final_b = max(0LL, val_b - reduction_b);
long long remaining_a = val_a + (budget % unit_cost);
double score2 = (double)remaining_a / (remaining_a + final_b);
cout << fixed << setprecision(9) << max(score1, score2) << endl;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int queries;
cin >> queries;
while (queries--) {
evaluate_review_score();
}
return 0;
}
Problem C: Greedy Scheduling for Maximum Activities
To solve the scheduling problem of maximizing activities while respecting time limits, a greedy strategy with a backtracking mechanism is effective. We initially assume that every activity is performed. As we iterate through the timeline, we track the accumulated available time.
If the accumulated time becomes negative, it means the current schedule is impossible. To fix this, we must retroactively "cancel" an activity. To stay greedy, we should cancel the activity that provides the largest time recovery—specifically, the activity with the greatest difference between its "active" time cost and its "idle" time cost. A priority queue (max-heap) is used to efficiently retrieve and remove these high-cost activities.
#include <iostream>
#include <vector>
#include <queue>
using namespace std;
void optimize_schedule() {
int activity_count;
cin >> activity_count;
priority_queue<long long> potential_savings;
long long net_time = 0;
int completed_tasks = activity_count;
for (int i = 0; i < activity_count; ++i) {
long long deadline, cost_active, cost_idle;
cin >> deadline >> cost_active >> cost_idle;
if (cost_active > cost_idle) {
potential_savings.push(cost_active - cost_idle);
}
net_time += (cost_idle - deadline);
while (net_time < 0) {
if (potential_savings.empty()) {
cout << -1 << endl;
return;
}
net_time += potential_savings.top();
potential_savings.pop();
completed_tasks--;
}
}
cout << completed_tasks << endl;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
optimize_schedule();
return 0;
}