1 条题解

  • 0
    @ 2024-6-13 2:22:32

    【题目大意】每头牛有攻击范围a[i]和b[i],如果他的左边 aia_i 个牛棚或者右边 bib_i 个牛棚有其他牛,它就会去挑事。问怎样排列才能使牛不互相攻击且牛棚长度最短。

    【考纲知识点】搜索、全排列

    【解题思路】

    首先观察到数据范围 n9n≤9,数据范围是很小的,且牛排列的位置不定。

    可以使用递归搜索的方式进行暴力枚举

    主函数的部分要注意的是输入+调用搜索+输出答案

    在进行搜索的时候注意优化代码进行减枝

    【参考程序】

    #include <bits/stdc++.h>
    using namespace std;
    const int N = 10;
    int n,a[N],b[N],mn = 1e9,vis[N],c[N];
    void dfs(int p,int ans)
    {
        if(p == n+1) //超过牛的数量的范围
        {
            mn = min(mn,ans);
            return ;
        }
        //最优性减枝:即使后面的牛只更新1,也无法更新最优解,直接返回
        if(ans+2*n-2*p+1>=mn)
        {
            return ;
        }
        for(int i = 1;i <= n;i++)
        {
            if(!vis[i])//未被标记
            {
                vis[i] = 1;
                c[p] = i;
                if(p != 1)//不是起点,继续搜下一个牛,注意加两端的大的范围
                {
                    dfs(p+1,ans+max(a[i],b[c[p-1]])+1);
                }
                else//是起点,搜下一个牛
                {
                    dfs(p+1,1);
                }
                vis[i] = 0;//回溯返回状态
            }
        }
    }
    int main()
    {
        cin >> n;
        for(int i = 1;i <= n;i++)
        {
            cin >> a[i];
        }
        for(int i = 1;i <= n;i++)
        {
            cin >> b[i];
        }
        dfs(1,0);//从第一个牛,需要牛棚0个开始搜索
        cout << mn;
        return 0;
    }
    
    • 1

    [GESP202403 六级] 好斗的牛

    信息

    ID
    651
    时间
    1000ms
    内存
    512MiB
    难度
    7
    标签
    递交数
    17
    已通过
    8
    上传者