赞
踩
目录
深度优先搜索算法(Depth First Search,简称DFS):一种用于遍历或搜索树或图的算法。 沿着树的深度遍历树的节点,尽可能深的搜索树的分支。当节点v的所在边都己被探寻过或者在搜寻时结点不满足条件,搜索将回溯到发现节点v的那条边的起始节点。整个进程反复进行直到所有节点都被访问为止。属于盲目搜索,最糟糕的情况算法时间复杂度为O(!n)。
沿着树的深度来遍历树的节点,尽可能深的搜索树的分支。当节点v的所有边都己被探寻过,搜索将回溯到发现节点v的那条边的起始节点。这一过程一直进行到已发现从源节点可达的所有节点为止。如果还存在未被发现的节点,则选择其中一个作为源节点并重复以上过程,整个进程反复进行直到所有节点都被访问为止。
- int check(参数)
- {
- if(满足条件)
- return 1;
- return 0;
- }
- void dfs(int step)
- {
- 判断边界
- {
- 相应操作
- }
- 尝试每一种可能
- {
- 满足check条件
- 标记
- 继续下一步dfs(step+1)
- 恢复初始状态(回溯的时候要用到)
- }
- }
- public class Main {
- private static int INF = 0x3f3f3f3f;
- static int a[] = {0,1,2,1,1,1,1,5,5,4,-1,-1,-2,-3,-1,-9};
- public static void main(String[] args) {
- dfs(0,0);
- System.out.println(dfs(0,0));
- }
- static int dfs(int idx, int k) {//idx是台阶数,k是步数
- if(idx == 15){
- return a[15];//最后一阶-9
- }
- if(k == 6) {//6步
- return -INF;
- }
- int ans = -INF;//得分
- for(int i=1;i <= 4 && idx + i <= 15;i++){
- ans = Math.max(ans, dfs(idx + i, k + 1));
- }
- return ans + a[idx];
- }
- }
法1
- import java.util.Scanner;
-
- public class Main{
- static int sum, cnt = 0x3f3f3f3f, value[] = new int[15];
- //宏定义一个0x3f3f3f3f可以减少考虑的时间,一般情况下就可以当作是一个无穷大的数去用
- public static void main(String[] args) {
- Scanner in = new Scanner(System.in);
- for (int i = 0; i < 15; i++)
- sum += value[i] = in.nextInt();//口罩总数
- dfs(0, 0);
- System.out.print(cnt);//口罩之差
- }
-
- static void dfs(int d, int v) {//d是口罩批数,v是医院分得的口罩数
- if (d == 15)
- cnt = min(cnt, abs(sum - v - v));//口罩之差
- else {
- dfs(d + 1, v + value[d]);
- dfs(d + 1, v);
- }
- }
-
- static int min(int a, int b) { return a < b? a: b; }
- static int abs(int a) { return a > 0? a: -a; }
- }
法2
- public class Main {
- public static long res=Long.MAX_VALUE;
- public static long num[]={9090400, 8499400, 5926800, 8547000, 4958200,
- 4422600, 5751200, 4175600, 6309600, 5865200,
- 6604400, 4635000, 10663400, 8087200, 4554000
- };
- public static void main(String[] args){
- dfs(0, 0, 0);
- System.out.println(res);
- }
- //k是口罩批数,sum1和sum2两家医院分得的口罩数
- public static void dfs(int k,long sum1,long sum2 ) {
- if(k==15) {
- res=res < Math.abs(sum1-sum2) ? res:Math.abs(sum1-sum2);
- return;
- }
- dfs(k+1, sum1+num[k], sum2);
- dfs(k+1, sum1, sum2+num[k]);
- }
- }
- public class Main {
- public static int N=10;
- public static int e[][]=new int[N][N];//存储二极管相邻的信息
- public static int f[]=new int[N];//并查集
- public static int ans=0;
- public static boolean st[]=new boolean[N];//true表示发光
- public static void init(){
- //表示相邻
- //1 2 3 4 5 6 7
- //a b c d e f g
- e[1][2]=e[1][6]=1;//a与b、f相邻
- e[2][1]=e[2][7]=e[2][3]=1;//b与a、g、c相邻
- e[3][2]=e[3][7]=e[3][4]=1;//c与b、g、d相邻
- e[4][3]=e[4][5]=1;//d与c、e相邻
- e[5][7]=e[5][6]=e[5][4]=1;//e与g、f、d相邻
- e[6][5]=e[6][7]=e[6][1]=1;//f与e、g、a相邻
- e[7][2]=e[7][3]=e[7][5]=e[7][6]=1;//g与b、c、e相邻
- }
-
- public static int find(int u){
- if(f[u]==u) return u;
- f[u]=find(f[u]);
- return f[u];
- }
-
- public static void dfs(int d){//1-7
- if(d>7){
- //终止条件
- for(int i=1;i<=7;i++){//并查集初始化
- f[i]=i;
- }
- for(int i=1;i<=7;i++){
- for(int j=1;j<=7;j++){
- if(e[i][j]==1&&st[i]==true&&st[j]==true){//把所有发光且相邻的二极管合并
- int fx=find(i),fy=find(j);
- if(fx!=fy){
- f[fx]=fy;//合并
- }
- }
-
- }
- }
- int k=0;//表示产生的集合的个数
- for(int i=1;i<=7;i++){
- if(st[i] &&f[i]==i)k++;
- }
- if(k==1) ans++;//只产生一个集合,说明所有的发光二极管是连成一片的
- return;
- }
-
- st[d]=true;
- dfs(d+1);
- st[d]=false;
- dfs(d+1);
- }
-
- public static void main(String[] args) {
- init();
- dfs(1);
- System.out.println(ans);
- }
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。