• 围栏问题 [搜索+最优化剪枝]



    Solutionmathcal{Solution}

    不合法方案的花费一定比最优解大

    有了这条隐含信息, 直接搜索, 方法如下 ,

    • 按顺序给每只兔子安排围墙,
    • 设当前搜到了 kk 只兔子, 有两个选择.
    1. 扩张前面所存在的围栏
    2. 只围住自己

    加上 最优化剪枝 即可 ACAC.


    #include<bits/stdc++.h>
    #define reg register
    
    int read(){
            char c;
            int s = 0, flag = 1;
            while((c=getchar()) && !isdigit(c))
                    if(c == '-'){ flag = -1, c = getchar(); break ; }
            while(isdigit(c)) s = s*10 + c-'0', c = getchar();
            return s * flag;
    }
    
    const int maxn = 25;
    
    int M;
    int K;
    int N;
    int Ans;
    int min_x[maxn];
    int min_y[maxn];
    int max_x[maxn];
    int max_y[maxn];
    
    struct Rabbit{ int x, y; } A[maxn];
    
    void DFS(int k, int cnt, int sum){
            if(sum >= Ans) return ;
            if(k > N){ Ans = sum; return ; }
            if(cnt < K){ 
                    min_x[cnt+1] = max_x[cnt+1] = A[k].x; 
                    min_y[cnt+1] = max_y[cnt+1] = A[k].y;
                    DFS(k+1, cnt+1, sum + 4);
            }
            if(k == 1) return ;
            for(reg int i = 1; i <= cnt; i ++){
                    int tx = A[k].x, ty = A[k].y;
                    int t_1 = min_x[i], t_2 = min_y[i], t_3 = max_x[i], t_4 = max_y[i];
                    int tmp = 2*(max_x[i]-min_x[i]+max_y[i]-min_y[i]);
                    min_x[i] = std::min(tx, min_x[i]);
                    min_y[i] = std::min(ty, min_y[i]);
                    max_x[i] = std::max(tx, max_x[i]);
                    max_y[i] = std::max(ty, max_y[i]);
                    tmp = 2*(max_x[i]-min_x[i]+max_y[i]-min_y[i]) - tmp;
                    DFS(k+1, cnt, sum + tmp);
                    min_x[i] = t_1, min_y[i] = t_2, max_x[i] = t_3, max_y[i] = t_4;
            }
    }
    
    int main(){
            M = read(); K = read(); N = read();
            for(reg int i = 1; i <= N; i ++)
                    A[i].x = read(), A[i].y = read();
            Ans = 0x3f3f3f3f;
            DFS(1, 0, 0);
            printf("%d
    ", Ans);
            return 0;
    }
    
  • 相关阅读:
    深入理解Java虚拟机二之Java内存区域与内存溢出异常
    深入理解java虚拟机一之走进Java
    数据结构之链表
    Spring AOP 详解
    Spring IOC 注入方式详解 附代码
    图的广度优先遍历
    图的深度优先遍历
    MySql 中的<=>操作符
    mysql数据库explain命令用法详解
    Java虚拟机内存分配详解
  • 原文地址:https://www.cnblogs.com/zbr162/p/11822609.html
Copyright © 2020-2023  润新知