DFS进阶——买瓜

买瓜
题目分析

使用dfs依次考虑每一个瓜,我是切开还是不切还是直接不买。这里u表示我当前考虑的瓜,res表示当前获得瓜的总重量,count表示切开瓜的次数。

dfs(u+1,res,count);//不买
dfs(u+1,res+a[u]/2,count+1);//切
dfs(u+1,res+a[u],count);//不切

考虑终点状态就是前n个瓜都遍历完了或者res恰好等于瓜的总重量的一半。

if(res == m){
    flag = 1;
    min = Math.min(min,count);
}
if(u>n)return;

考虑剪枝,如果当前瓜的切开次数大于等于了我之前记录的最小值,那么就返回。如果当前瓜的重量已经超过了瓜的总重量的一半,那么就返回。还可以考虑什么?如果当前未遍历到的瓜的总重量加到当前已经拥有的总重量上小于瓜的总重量的一半,说明我后面即便全要了也不会使res恰好等于瓜的总重量的一半,那么就返回。

if(res+sum[u]<m||res>m||count >= min){//剪枝
    return ;
}

这里的sum[u]就是一个后缀和,表示第u个瓜到第n个瓜的总重量。我们可以在dfs之前预处理出来。

sum = new long[n+1];
for(int i = n-1; i >=0; i --){
    sum[i] = sum[i+1]+a[i];
}

最后考虑我们希望尽快的凑齐瓜的总重量的一半,其实可以优先选择重量大的瓜,所以我们可以对瓜的重量进行从大到小的排序。

Arrays.sort(a, new Comparator<Long>() {
    @Override
    public int compare(Long o1, Long o2) {
        return (int) (o2-o1);
    }
});
题目代码
import java.util.Arrays;
import java.util.Comparator;
import java.util.Scanner;
public class Main{
    static int n ;
    static int m;
    static Long []a ;
    static long []sum;
    static int flag = 0;
    static int min = Integer.MAX_VALUE;
    public static void main(String[] args) {
        Scanner s = new Scanner(System.in);
        n = s.nextInt();
        m = s.nextInt()*2;
        a = new Long [n];
        for(int i = 0; i < n; i ++){
            a[i] = s.nextLong()*2;
        }
        Arrays.sort(a, new Comparator<Long>() {
            @Override
            public int compare(Long o1, Long o2) {
                return (int) (o2-o1);
            }
        });
        sum = new long[n+1];
        for(int i = n-1; i >=0; i --){
            sum[i] = sum[i+1]+a[i];
        }
        dfs(0,0,0);
        if(flag==1)
            System.out.println(min);
        else
            System.out.println(-1);
    }
    public static void dfs(int u,long res,int count){
        //u表示选择过的西瓜数,res表示目前有的重量,count表示切瓜次数
        if(res == m){
            flag = 1;
            min = Math.min(min,count);
        }
        if(u>n)return;
        if(res+sum[u]<m||res>m||count >= min){//剪枝
            return ;
        }
        dfs(u+1,res,count);//不买
        dfs(u+1,res+a[u]/2,count+1);//切
        dfs(u+1,res+a[u],count);//不切
    }
}
  • 4
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
DFS深度优先搜索)可以用于解决迷宫出口问。 首先,我们需要将迷宫转化为图,其中每个房间是图中的一个节点,每个房间之间的通道是图中的一条边。我们可以用一个二维数组来表示迷宫,其中0表示墙,1表示通道。 然后,我们可以使用DFS来搜索迷宫。我们从起点开始探索,每次选择一个未被访问的相邻节点进行探索,直到找到出口为止。为了避免陷入死循环,我们需要记录已经访问过的节点。 具体实现可以使用递归或者栈来实现DFS,以下是一个使用递归的示例代码(假设起点为(0,0),出口为(n-1,m-1)): ```python def dfs(x, y, visited, maze): # 判断当前节点是否为出口 if x == len(maze)-1 and y == len(maze[0])-1: return True # 标记当前节点已被访问 visited[x][y] = True # 搜索相邻节点 for dx, dy in [(0,1), (0,-1), (1,0), (-1,0)]: nx, ny = x+dx, y+dy # 判断相邻节点是否合法 if 0 <= nx < len(maze) and 0 <= ny < len(maze[0]) and maze[nx][ny] == 1 and not visited[nx][ny]: # 递归搜索相邻节点 if dfs(nx, ny, visited, maze): return True return False # 测试 maze = [ [1, 0, 1, 1, 1], [1, 0, 1, 0, 1], [1, 0, 1, 0, 1], [1, 1, 1, 0, 1], [0, 0, 0, 0, 1] ] visited = [[False for _ in range(len(maze[0]))] for _ in range(len(maze))] print(dfs(0, 0, visited, maze)) # 输出True,表示存在从起点到出口的路径 ``` 这段代码中,dfs函数的参数分别表示当前搜索的节点坐标、已经访问过的节点、迷宫的二维数组。搜索过程中,我们先判断当前节点是否为出口,如果是,则返回True。然后标记当前节点已被访问,并搜索相邻节点,如果找到了一个相邻节点可以到达出口,则返回True。否则,返回False表示无法到达出口。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值