CF1574 D. The Strongest Build(BFS+剪枝)

目录

Description

\(n\) 种卡片,每种卡片选一张,有 \(m\) 种选择是不可以被选的,输出卡片总和最大的选择

State

\(1<=n<=10\)

\(1<=ci<=2*10^5\)

\(1<=a_{i1}<=a_{i2}<=...a_{ik}<=10^8\)

\(0<=m<=10^5\)

\(1<=b_i<=c_i\)

Input

3
3 1 2 3
2 1 5
3 2 4 6
2
3 2 3
3 2 2

Output

2 2 3 

Solution

最大值一定是每一种都挑选最后一个,次大值就是第 \(i\) 种卡片换成次大值,其中 \(i\) 满足次大值与最大值的差距最小,第三大值的情况就多起来了;

按上述思路处理出每个值之间的差,无论时间还是空间都是受不了的

但是可以搜索,利用优先队列,以和值作为关键字排序,时间上最多 \(m\) 次,空间上会出问题,例如样例 \(1\) :

\[3\qquad 2\qquad 3 \\ 223 \quad 313\quad 322 \\ 123\ 213\ 222\ 213\ 303\ 312\ 222\ 312\ 321 \]

从第 \(3\) 层开始,就出现了重复的,那么将这些重复的减去,空间上的问题就解决了


Code

const int N = 2e5 + 5;

    int n, m, _, k;
    int a[15][N];

signed main()
{
    //IOS;
    while(~ sd(n)){
        map<vector<int>, bool> b, vis;
        vector<int> res;
        ll sum = 0;
        rep(i, 0, n - 1){
            sd(k);
            res.pb(k - 1);
            rep(j, 0, k - 1){
                sd(a[i][j]);
            }
            sum += a[i][k - 1];
        }
        priority_queue<pair<ll, vector<int>>> q;
        q.push({sum, res});
        //for(auto it : res) dbg(it);
        sd(m);
        rep(i, 1, m){
            res.clear();
            rep(j, 1, n){
                res.pb(read() - 1);
            }
            b[res] = 1;
        }
        vector<int> ans;
        ll maxx = 0;
        while(! q.empty()){
            vector<int> top = q.top().second;
            sum = q.top().first;
            q.pop();
            if(b[top]){
                for(int i = 0; i < n; i ++){
                    if(top[i] == 0) continue;
                    sum -= a[i][top[i]];
                    top[i] --;
                    sum += a[i][top[i]];
                    if(vis[top] == 0){
                        q.push({sum, top});
                        vis[top] = 1;
                    }
                    sum -= a[i][top[i]];
                    top[i] ++;
                    sum += a[i][top[i]];
                }
            }
            else{
                maxx = sum;
                ans = top;
                break;
            }
        }
        for(auto it : ans){
            printf("%d ", it + 1);
        }
        puts("");
    }
    //PAUSE;
    return 0;
}
posted @ 2021-09-25 12:48  Bcoi  阅读(55)  评论(0)    收藏  举报