The Strongest Build(bfs+优先队列)
题目链接
题意:
有\(n\)个从小到大的数组,从每个数组中选取一个下标构成长度为\(n\)的序列,但有\(m\)个序列被禁止,求不属于禁止序列且下标对应元素和最大的序列。
思路:
首先得到元素和最大的序列,即为每个数组最后一个元素构成的序列,若该序列不属于禁止序列,则该系列为所求序列。否则由该序列进行\(bfs\)搜索,替换其中某个元素,求得其次大值序列,若该序列没有被访问,则将值和序列放入优先队列。每次从优先队列中取出值最大的序列,若序列不在禁止序列中,则输出该序列,否则继续进行\(bfs\)搜索。只有\(m\)个禁止序列,且\(n<=10\),所以最多进行\(m*10\)次搜索就可得到答案。用\(hash\)表记录禁止序列和访问过的序列(也可用\(map、set\)记录,\(hash\)表取进制\(p=131\)会\(wa\)第41个点,可取\(p=13331\))。
code:
#include <iostream>
#include <cstdio>
#include <string>
#include <cstring>
#include <algorithm>
#include <queue>
#include <vector>
#include <deque>
#include <cmath>
#include <ctime>
#include <map>
#include <set>
#include <unordered_map>
#define fi first
#define se second
#define pb push_back
#define endl "\n"
#define debug(x) cout << #x << ":" << x << endl;
#define bug cout << "********" << endl;
#define all(x) x.begin(), x.end()
#define lowbit(x) x & -x
#define fin(x) freopen(x, "r", stdin)
#define fout(x) freopen(x, "w", stdout)
#define ull unsigned long long
#define ll long long
const double eps = 1e-15;
const int inf = 0x3f3f3f3f;
const ll INF = 0x3f3f3f3f3f3f3f3f;
const double pi = acos(-1.0);
const int mod = 998244353;
const int maxn = 2e5 + 10;
using namespace std;
#define piv pair<int, vector<int>>
int s[12], n, m, w[12][maxn];
priority_queue<piv> q;
unordered_map<ull, bool> mp, ban;
ull get(vector<int> &v){
ull ret = 0;
for(auto i : v)ret = ret * 13331 + i;
return ret;
}
int main(){
piv ans; int ret = 0;
vector<int> k;
scanf("%d", &n);
for(int i = 1; i <= n; i ++){
scanf("%d", &s[i]);
for(int j = 1, a; j <= s[i]; j ++){
scanf("%d", &w[i][j]);
}
ret += w[i][s[i]], k.pb(s[i]);
}
q.push(make_pair(ret, k));
scanf("%d", &m);
for(int i = 1; i <= m; i ++){
k.clear();
for(int j = 1, a; j <= n; j ++){
scanf("%d", &a);
k.pb(a);
}
ban[get(k)] = 1;
}
while(q.size()){
piv p;
p = q.top(); q.pop();
if(!ban[get(p.se)]){ans = p; break;}
for(int i = 0; i < n; i ++){
if(p.se[i] > 1){
piv p1 = p;
p1.fi += w[i + 1][p1.se[i] - 1] - w[i + 1][p1.se[i]];
p1.se[i] -= 1;
if(!mp[get(p1.se)])mp[get(p1.se)] = 1, q.push(p1);
}
}
}
for(int i = 0; i < n; i ++)printf("%d ", ans.se[i]);
return 0;
}

浙公网安备 33010602011771号