hdu 1045 DFS+回溯

本文介绍了一种使用暴力搜索方法解决大炮布局问题,即在一个nxn矩阵中放置大炮,使得任意两门大炮之间不存在攻击路径,通过回溯算法实现最优解的求解。
摘要由CSDN通过智能技术生成

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1045
题目描述:给你一个n x n的矩阵,若该点不为障碍,则可以放置大炮,大炮可向上下左右4个方向开炮,所以若同一行或同一列存在2门大炮并且他们之间没有障碍,则会出现互相攻击,当然我们不希望这种情况出现。现在问你最多能放置多少门大炮并且他们不能互相攻击。
解题思路:对于每个点,若能放置大炮则能选择放或者不放两种情况,若不能放置大炮则就只有一种情况。由于题目的数据规模很小,n<=4. 所以可以使用暴力搜索。注意回溯的时候要恢复点的状态.

 

HDU 4109是一道经典的算法题,题目要求求解一个图的最大独立集。最大独立集是指在图中选出最多的顶点,使得这些顶点之间没有任何边相连。对于这道题,可以使用多种方法来解决,包括动态规划、贪心算法和回溯法等。 以下是几种使用Java实现的代码示例: ### 方法一:动态规划 ```java import java.util.*; public class Main { public static void main(String[] args) { Scanner sc = new Scanner(System.in); while (sc.hasNext()) { int n = sc.nextInt(); int m = sc.nextInt(); List<List<Integer>> graph = new ArrayList<>(); for (int i = 0; i <= n; i++) { graph.add(new ArrayList<>()); } for (int i = 0; i < m; i++) { int u = sc.nextInt(); int v = sc.nextInt(); graph.get(u).add(v); graph.get(v).add(u); } boolean[] visited = new boolean[n + 1]; System.out.println(dfs(graph, visited, 1, n)); } sc.close(); } private static int dfs(List<List<Integer>> graph, boolean[] visited, int u, int n) { visited[u] = true; int size = 1; for (int v : graph.get(u)) { if (!visited[v]) { size += dfs(graph, visited, v, n); } } return size; } } ``` ### 方法二:贪心算法 ```java import java.util.*; public class Main { public static void main(String[] args) { Scanner sc = new Scanner(System.in); while (sc.hasNext()) { int n = sc.nextInt(); int m = sc.nextInt(); List<List<Integer>> graph = new ArrayList<>(); for (int i = 0; i <= n; i++) { graph.add(new ArrayList<>()); } for (int i = 0; i < m; i++) { int u = sc.nextInt(); int v = sc.nextInt(); graph.get(u).add(v); graph.get(v).add(u); } boolean[] visited = new boolean[n + 1]; int count = 0; for (int i = 1; i <= n; i++) { if (!visited[i]) { count++; dfs(graph, visited, i); } } System.out.println(count); } sc.close(); } private static void dfs(List<List<Integer>> graph, boolean[] visited, int u) { visited[u] = true; for (int v : graph.get(u)) { if (!visited[v]) { dfs(graph, visited, v); } } } } ``` ### 方法三:回溯法 ```java import java.util.*; public class Main { public static void main(String[] args) { Scanner sc = new Scanner(System.in); while (sc.hasNext()) { int n = sc.nextInt(); int m = sc.nextInt(); List<List<Integer>> graph = new ArrayList<>(); for (int i = 0; i <= n; i++) { graph.add(new ArrayList<>()); } for (int i = 0; i < m; i++) { int u = sc.nextInt(); int v = sc.nextInt(); graph.get(u).add(v); graph.get(v).add(u); } boolean[] visited = new boolean[n + 1]; System.out.println(backtrack(graph, visited, 1, n)); } sc.close(); } private static int backtrack(List<List<Integer>> graph, boolean[] visited, int u, int n) { if (u > n) return 0; int res = 0; for (int i = u; i <= n; i++) { if (!visited[i]) { visited[i] = true; for (int v : graph.get(i)) { visited[v] = true; } res = Math.max(res, 1 + backtrack(graph, visited, i + 1, n)); for (int v : graph.get(i)) { visited[v] = false; } visited[i] = false; } } return res; } } ``` 以上三种方法分别使用了动态规划、贪心算法和回溯法来解决这个问题。你可以根据具体需求选择合适的方法进行实现。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值