rt,我的程序跑出来比正确答案还要优。。。
#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
#include <vector>
#include <ctime>
#define POPULATION 100
#define TIMES 1000
using namespace std;
const int N = 110, M = 21;
int a[N][M], n, m, K, ans = 0x3f3f3f3f;
int random(int l, int r) {
return rand() % (r - l + 1) + l;
}
struct Individual {
vector<int> p;
int fitness;
Individual(vector<int> p);
Individual mate();
int calc_fitness();
bool operator < (const Individual& tmp)const {
return fitness < tmp.fitness;
}
};
Individual::Individual(vector<int> P) {
this -> p = P;
this -> fitness = calc_fitness();
}
Individual Individual::mate() {
vector<int> _p = this -> p;
int P = random(0, 3);
for (int i = 1; i <= P; i ++ ) {
int pos1 = random(0, n - 1), pos2 = random(1, n - 1);
swap(_p[pos1], _p[pos2]);
}
return _p;
}
int Individual::calc_fitness() {
int state = 0;
for (int i = 0; i < n; i ++ ) {
for (int j = 0; j < K; j ++ )
state |= (1 << a[p[i]][j] - 1);
if (state == (1 << m) - 1) return i + 1;
}
puts("-1"); exit(0);
}
int main() {
scanf("%d%d%d", &n, &m, &K);
for (int i = 0; i < n; i ++ )
for (int j = 0; j < K; j ++ )
scanf("%d", &a[i][j]);
vector<Individual> population; vector<int> P;
for (int i = 0; i < n; i ++ ) P.push_back(i);
for (int i = 1; i <= POPULATION; i ++ ) {
random_shuffle(P.begin(), P.end());
population.push_back(Individual(P));
}
for (int i = 0; i < TIMES; i ++ ) {
sort(population.begin(), population.end());
ans = min(ans, population[0].fitness);
vector<Individual> new_population;
int s = (10 * POPULATION) / 100;
for (int i = 0; i < s; i ++ )
new_population.push_back(population[i]);
s = POPULATION - s;
for (int i = 0; i < s; i ++ ) {
Individual p = population[random(0, 50)];
new_population.push_back(p.mate());
}
}
printf("%d\n", ans);
return 0;
}