2024.08.03米哈游秋招第一场

1. 数组价值

米小游有一个长度为 n 的数组,其中第 i 个元素为 ai。现在定义数组的价值是最大的相邻数字的乘积。
例如数组为 [3,5,1,2] ,相邻元素的乘积分别是 35=15,51=5和1*2=2 ,则数组的价值是这些数字中的最大值,即 15。
现在米小游想要任选数组中的某两个相邻的元素进行交换(你必须使用这次交换机会),他想知道最大可以将数组的价值更改为多少?

观察计算相邻和间隔一位乘积最大值即可
int main() {
    int n;
    cin>>n;
    vector<int> nums(n);
    for(int i=0;i<n;i++)
        cin>>nums[i];
    long long res = 0;
    for(int i=0;i<n-1;i++){
        if(i<n-2) res = max(res,(long long)nums[i]*nums[i+2]);
        res = max(res,(long long)nums[i]*nums[i+1]);
    }
    cout<<res;
    return 0;
}

2. 米小游买商品

商店里有 n个商品,分别编号为 1~n ,每个商品都有一个价值 vali和体积 wi,米小游有一个有一个 m 容量的背包,他能够装得下任意多个体积之和不超过 m 的商品。
米小游认为有些东西一起购买会带来灾难,比如可莉的角色立牌和蹦蹦炸弹的小手办,
所以他设定了 k组互斥关系,每组关系给定两个数字 a,b,表示编号为 a 的商品和编号为 b的商品不能同时购买。
米小游希望装下的物品的价值之和最大,请你帮帮他求出最大价值。

暴力回溯搜索,注意撤回选择的时候,不能把另一个互斥关系撤回,所以要采用多重加锁

int main() {
    int n,m,k;//商品数量,背包容量,互斥关系
    cin>>n>>m>>k;
    vector<vector<int>> items(n,vector<int>(2));
    vector<vector<int>> relation(k,vector<int>(2));
    for(int i=0;i<n;i++)
        cin>>items[i][0]>>items[i][1];//体积和价值
    unordered_map<int,int> mp;//互斥关系1~n
    for(int i=0;i<k;i++){
        cin>>relation[i][0]>>relation[i][1];
        mp[relation[i][0]-1] = relation[i][1]-1;
        mp[relation[i][1]-1] = relation[i][0]-1;
    }
    //正常是背包动态规划,但由于数据量n很小,以及存在互斥,直接使用暴搜
    function<int(int,int,vector<int>&)> dfs = [&](int i,int capacity,vector<int>&h)->int{
        if(i==n) return 0;//访问完毕边界
        int res = 0;
        res = max(res,dfs(i+1,capacity,h));//不选
        if(h[i]==0&&items[i][0]<=capacity){//选
            h[mp[i]]++;
            res = max(res,items[i][1]+dfs(i+1,capacity-items[i][0],h));
            h[mp[i]]--;
        }
        return res;
    };
    vector<int> memo(n,0);
    cout<<dfs(0,m,memo);
    
    return 0;
}

3. 删点

米小游和派蒙在进行一场游戏。游戏在一个基环树(点数与边数相等的无向简单连通图)上进行,
定义图中一个点的度数为与其相连的边数,二人轮流进行以下操作:
选择图中一个度数为 1 的点,删除这个点以及与这个点相连的边。
图中有一个特殊的点 x ,删除了点 x 的玩家即获得胜利。现在,由米小游先进行操作。在双方都采取最优策略的情况下,胜者是谁?

拓扑排序,同时找出规律
也就是位于环上,即度不能为1,找不到,不位于环上,若是第一个,则玩家一胜利,否则看找到前能删除的点个数是奇数还是偶数

int main() {
    int T;
    cin>>T;
    while(T--){
        int n,x;
        cin>>n>>x;
        vector<vector<int>> graph(n+1);
        queue<int> q;//入度为1的队列
        vector<int> cnt(n+1);//入度的数量
        for(int i=0;i<n;i++){
            int from,to;
            cin>>from>>to;
            graph[from].push_back(to);
            graph[to].push_back(from);
            cnt[from]++;
            cnt[to]++;
        }
        for(int i=1;i<=n;i++)
            if(cnt[i]==1) q.push(i);
        bool find = false;
        bool first = true;
        int res = 0;
        while(!q.empty()){
            int cur = q.front();
            q.pop();
            if(cur==x){
                find = true;
                continue;
            }
            for(auto next:graph[cur]){
                if(next==x) first = false;
                cnt[next]--;
                if(cnt[next]==1) q.push(next);
            }
            res++;
        }
        if(find==false) cout<<"Draw";
        else{
            
            if(first||res%2==0) cout<<"Xiaoyo";
            else cout<<"Pyrmont";
        }
    }
    return 0;
}
posted @ 2024-09-04 21:29  失控D大白兔  阅读(24)  评论(0编辑  收藏  举报