#include <bits/stdc++.h>
#include <ctime>
using namespace std;
const int POPULATION_SIZE = 5000;
const double MUTATION_RATE = 0.4;
int n;
long long x;
vector<long long> w;
struct Individual {
vector<int> chromosome;
int rides;
double fitness;
};
void evaluate(Individual& ind) {
int current_rides = 1;
long long current_weight = 0;
double sum_squares = 0;
for (int idx : ind.chromosome) {
if (current_weight + w[idx] <= x) {
current_weight += w[idx];
} else {
sum_squares += pow((double)current_weight / x, 2);
current_rides++;
current_weight = w[idx];
}
}
sum_squares += pow((double)current_weight / x, 2);
ind.rides = current_rides;
ind.fitness = sum_squares / current_rides;
}
Individual crossover(const Individual& p1, const Individual& p2) {
Individual child;
child.chromosome.assign(n, -1);
int left = rand() % n;
int right = rand() % n;
if (left > right) swap(left, right);
vector<bool> in_child(n, false);
for (int i = left; i <= right; ++i) {
child.chromosome[i] = p1.chromosome[i];
in_child[p1.chromosome[i]] = true;
}
int curr_p2 = 0;
for (int i = 0; i < n; ++i) {
if (child.chromosome[i] == -1) {
while (in_child[p2.chromosome[curr_p2]]) {
curr_p2++;
}
child.chromosome[i] = p2.chromosome[curr_p2];
in_child[p2.chromosome[curr_p2]] = true;
}
}
return child;
}
void mutate(Individual& ind) {
if ((double)rand() / RAND_MAX < MUTATION_RATE) {
int i = rand() % n;
int j = rand() % n;
swap(ind.chromosome[i], ind.chromosome[j]);
}
}
int main() {
ios_base::sync_with_stdio(false);
cin.tie(NULL);
srand(time(NULL));
double start_time = clock();
cin >> n >> x;
w.resize(n);
for (int i = 0; i < n; ++i) cin >> w[i];
vector<Individual> population(POPULATION_SIZE);
int best_global_rides = n;
for (int i = 0; i < POPULATION_SIZE; ++i) {
population[i].chromosome.resize(n);
iota(population[i].chromosome.begin(), population[i].chromosome.end(), 0);
random_shuffle(population[i].chromosome.begin(), population[i].chromosome.end());
evaluate(population[i]);
best_global_rides = min(best_global_rides, population[i].rides);
}
while ((double)(clock() - start_time) / CLOCKS_PER_SEC < 0.90) {
sort(population.begin(), population.end(), [](const Individual& a, const Individual& b) {
return a.fitness > b.fitness;
});
vector<Individual> new_population;
int elitism_count = POPULATION_SIZE / 10;
for (int i = 0; i < elitism_count; ++i) {
new_population.push_back(population[i]);
}
while (new_population.size() < POPULATION_SIZE) {
int p1_idx = rand() % (POPULATION_SIZE / 2);
int p2_idx = rand() % (POPULATION_SIZE / 2);
Individual child = crossover(population[p1_idx], population[p2_idx]);
mutate(child);
evaluate(child);
best_global_rides = min(best_global_rides, child.rides);
new_population.push_back(child);
}
population = new_population;
}
cout << best_global_rides << "\n";
return 0;
}