CF edu114 D题
题意
有n(1<=n<=10)个桶,每个桶有最ci个数字(从小到大),下标为1到ci,有m个(1<=m<=1e5)被禁止选择的组合
问剩下可以选择的组合中 组合对应的数值和最大的 情况的 组合(如果最大的有好几个,任意输出其中一个)
题解
就是普通的bfs,但是重载运算符比较麻烦
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int MAX = 2e5 + 1000;
const ll INF = 0x3f3f3f3f3f3f3f3f;
struct node {
ll sum;
int cnt[11];
bool operator<(const node &a) const {//重载set的排序
if (sum != a.sum) return sum > a.sum;
for (int i = 0; i < 10; i++) {
if (cnt[i] != a.cnt[i]) return cnt[i] < a.cnt[i];
}
return 0;//要记得返回
}
};
struct cmp {
bool operator()(node a, node b) {
return a.sum < b.sum;
}
};
ll a[12][MAX];
int cnt[12];
set<node> have;
set<node> before;
int main() {
int n;
scanf("%d", &n);
for (int i = 0; i < n; i++) {
scanf("%d", &cnt[i]);
for (int j = 0; j < cnt[i]; j++) {
ll x;
scanf("%lld", &x);
a[i][j] = x;
}
}
int m;
scanf("%d", &m);
while (m--) {
node t;
ll tmp = 0;
for (int i = 0; i < n; i++) {
ll x;
scanf("%lld", &x);
t.cnt[i] = x - 1;
tmp += a[i][t.cnt[i]];
}
for (int i = n; i < 11; i++) {
t.cnt[i] = 0;
}
t.sum = tmp;
have.insert(t);
}
priority_queue<node, vector<node>, cmp> que;
node t;
t.sum = 0;
for (int i = 0; i < n; i++) {
t.sum += a[i][cnt[i] - 1];
t.cnt[i] = cnt[i] - 1;
}
for (int i = n; i < 11; i++) {
t.cnt[i] = 0;
}
que.push(t);
before.insert(t);
while (que.size()) {
node t = que.top();
for (int i = n; i < 10; i++) {
t.cnt[i] = 0;
}
if (have.count(t)) que.pop();
else {
for (int i = 0; i < n; i++) {
printf("%d ", t.cnt[i] + 1);
}
printf("\n");
return 0;
}
node s = t;
for (int i = 0; i < n; i++) {
ll x = s.cnt[i];
if (t.cnt[i] - 1 >= 0) {
s.cnt[i] = t.cnt[i] - 1;
s.sum = 0;
for (int j = 0; j < n; j++) {
s.sum += a[j][s.cnt[j]];
}
if (before.count(s)) {
s.cnt[i] = x;
} else {
que.push(s);
before.insert(s);
s.cnt[i] = x;
}
}
}
}
}