关于DFS的一点总结

今天在刷 USACO 2.1 PROB Healthy Holsteins

这题需要以这种方式搜索 1 ~ n

以n = 4 为例:

搜索顺序为:

(1),(2),(3),(4),

(1,2),(1,3),(1,4) ,(2,3),(2,4),(3,4)

(1,2,3),(1,2,4) , (1,3,4)

(1,2,3,4)

——

因为每次搜索的数字位数不同,所以需要用到递归。

递归在这里是决定循环层数的(循环和递归决定的维度不同)

但是这种dfs一直不会写。

今天看了别人的代码,死啃很久,Step one by one 好久。

大概能理解了。

把递归一方面看成是一个整体,高度抽象出来。只关注每次递归的意思

比如 dfs(t+1) 表示的在确定第t位后,确定第t+1是否拿,拿到第几个?

——

我以为我理解了dfs,突然发现自己对他的理解还是很浅薄。

讲不出来什么。

——

代码如下:

 1 /*
 2 ID:xiekeyi1
 3 PROG:holstein
 4 LANG:C++
 5 */
 6 #include<bits/stdc++.h>
 7 using namespace std ;
 8 const int maxn = 30 ;
 9 int v , vv[maxn] , g , gg[maxn][maxn];
10
11 void init()
12 {
13     cin >> v ;
14     for( int i = 1 ; i <= v ; i++)
15         cin >> vv[i];
16     cin >> g ;
17     for( int i = 1 ; i <= g ; i++)
18         for( int j = 1 ; j <= v ; j++)
19             cin >> gg[i][j];
20 }
21
22 bool flag = false ;
23 int num[maxn];
24 int cnt = 0 ;
25 int k = 1 ;
26 void work()
27 {
28     int a[30] = {0};
29     for( int i = 1 ; i <= cnt  ; i++)
30         for( int j = 1 ; j <=  v ; j++)
31             a[j] += gg[ num[i] ][j] ;
32     for( int i = 1 ; i <= v ; i++)
33         if( a[i] < vv[i] )
34             return ;
35
36     flag = true ;
37     cout << cnt ;
38     for( int i = 1 ; i <= cnt ; i++)
39         cout << ‘ ‘ << num[i] ;
40     cout << endl ;
41 }
42
43 void dfs( int t )
44 {
45     if( flag || t > g ) return ;
46     if( cnt >= k )
47     {
48         work() ;
49         return ;
50     }
51
52     cnt++;
53     num[cnt] = t + 1 ;
54     dfs( t + 1 ) ;
55     cnt--;
56     dfs( t + 1 ) ;
57     return ;
58 }
59
60
61 int main()
62 {
63     freopen("holstein.in","r",stdin);
64     freopen("holstein.out","w",stdout);
65     init() ;
66     while( !flag )
67     {
68         dfs(0);
69         k++;
70     }
71     return  0 ;
72 }

Healthy Holsteins
Burch & Kolstad

Farmer John prides himself on having the healthiest dairy cows in the world. He knows the vitamin content for one scoop of each feed type and the minimum daily vitamin requirement for the cows. Help Farmer John feed his cows so they stay healthy while minimizing the number of scoops that a cow is fed.

Given the daily requirements of each kind of vitamin that a cow needs, identify the smallest combination of scoops of feed a cow can be fed in order to meet at least the minimum vitamin requirements.

Vitamins are measured in integer units. Cows can be fed at most one scoop of any feed type. It is guaranteed that a solution exists for all contest input data.

PROGRAM NAME: holstein

INPUT FORMAT

Line 1: integer V (1 <= V <= 25), the number of types of vitamins
Line 2: V integers (1 <= each one <= 1000), the minimum requirement for each of the V vitamins that a cow requires each day
Line 3: integer G (1 <= G <= 15), the number of types of feeds available
Lines 4..G+3: V integers (0 <= each one <= 1000), the amount of each vitamin that one scoop of this feed contains. The first line of these G lines describes feed #1; the second line describes feed #2; and so on.

SAMPLE INPUT (file holstein.in)

4
100 200 300 400
3
50   50  50  50
200 300 200 300
900 150 389 399

OUTPUT FORMAT

The output is a single line of output that contains:

  • the minimum number of scoops a cow must eat, followed by:
  • a SORTED list (from smallest to largest) of the feed types the cow is given

If more than one set of feedtypes yield a minimum of scoops, choose the set with the smallest feedtype numbers.

SAMPLE OUTPUT (file holstein.out)

2 1 3

题意:

农民JOHN以拥有世界上最健康的奶牛为傲。他知道每种饲料中所包含的牛所需的最低的维他命量是多少。请你帮助农夫喂养他的牛,以保持它们的健康,使喂给牛的饲料的种数最少。

给出牛所需的最低的维他命量,输出喂给牛需要哪些种类的饲料,且所需的饲料剂量最少。

维他命量以整数表示,每种饲料最多只能对牛使用一次,数据保证存在解

PROGRAM NAME: holstein

INPUT FORMAT:

(file holstein.in)

第1行:一个整数V(1<=V<=25),表示需要的维他命的种类数。

第2行:V个整数(1<=每个数<=1000),表示牛每天需要的每种维他命的最小量。

第3行:一个整数G(1<=G<=15),表示可用来喂牛的饲料的种数。

下面G行,第n行表示编号为n饲料包含的各种维他命的量的多少。

OUTPUT FORMAT:

(file holstein.out)

输出文件只有一行,包括

牛必需的最小的饲料种数P

后面有P个数,表示所选择的饲料编号(按从小到大排列)。

如果有多个解,输出饲料序号最小的(即字典序最小)。

(摘自NOCOW)

时间: 2024-12-25 11:41:31

关于DFS的一点总结的相关文章

树的直径

*总结的别人博客 树的直径(Diameter)是指树上的最长简单路.直径的求法:两遍BFS (or DFS)任选一点u为起点,对树进行BFS遍历,找出离u最远的点v以v为起点,再进行BFS遍历,找出离v最远的点w.则v到w的路径长度即为树的直径*简单证明于是原问题可以在O(E)时间内求出 关键在于证明第一次遍历的正确性,也就是对于任意点u,距离它最远的点v一定是最长路的一端.如果u在最长路上,那么v一定是最长路的一端.可以用反证法:假设v不是最长路的一端,则存在另一点v’使得(u→v’)是最长路

8.12联考题解

所谓今天的题格外水,dalao们纷纷AK--但是本蒟蒻并没有看出来有多水啊--虽然还是水过了一道题,然后剩下的题就照常地转不过来弯,分数和往常并没有多大变化= =. 灌水 时间限制:1s 空间限制:256MB 样例输入1: 3 1 样例输出1: 3 1 2 样例输入2: 4 1 样例输出2: 4 3 1 2 样例输入3: 8 17 样例输出3: 6 2 3 1 8 4 5 7 题解       这个题,第一眼看过去很interesting,第二眼看过去一脸茫然--头一遍读题的时候看到数据范围里那

树的直径、树的重心与树的点分治

树的直径 树的直径(Diameter)是指树上的最长简单路. 直径的求法:两遍搜索 (BFS or DFS) 任选一点w为起点,对树进行搜索,找出离w最远的点u. 以u为起点,再进行搜索,找出离u最远的点v.则u到v的路径长度即为树的直径. 简单证明: 如果w在直径上,那么u一定是直径的一个端点.反证:若u不是端点,则从直径另一端点到w再到u的距离比直径更长,与假设矛盾. 如果w不在直径上,且w到其距最远点u的路径与直径一定有一交点c,那么由上一个证明可知,u是直径的一个端点. 如果w到最远点u

hdu 4771 求一点遍历所有给定点的最短路(bfs+dfs)

题目如题.题解如题. 由于目标点最多只有4个,先bfs出俩俩最短路(包括起点),再dfs最短路.)0s1A;(当年弱跪杭州之题,现看如此简单) #include<iostream> #include<vector> #include<cstdio> #include<cstring> #include<queue> using namespace std; struct point { int x,y; int cnt; }; char a[10

hdu 2821 学习一点dfs的小技巧吧。。 还是自己太弱了

#include<iostream> #include<cstdio> #include<cstring> using namespace std; int r,c,s,flag; int dir[4][2] = {{1,0},{-1,0},{0,1},{0,-1}}; char mapp[25][25],road[1000],d[5] = {"DURL"}; bool check(int x,int y) { if(x < 0 || x &g

hdu 4771 求一点遍历全部给定点的最短路(bfs+dfs)

题目如题.题解如题. 因为目标点最多仅仅有4个,先bfs出俩俩最短路(包含起点).再dfs最短路.)0s1A;(当年弱跪杭州之题,现看如此简单) #include<iostream> #include<vector> #include<cstdio> #include<cstring> #include<queue> using namespace std; struct point { int x,y; int cnt; }; char a[1

关于DFS一点微小想法

1.数字排列 这种问题有两种解决思想: A.一个一个去尝试(枚举) B.通过一个开始点去寻找(DFS) 相同点:都会先定住一个树.比如:对"1.2.3"这三个数进行全排列,人们总会先定住一个数(这里我定住"1"),这样下来变化范围就变小了而且这个变化可以控制了("23","32"). 总结一下就是:当第一个数字位为"1"时有两种排列方式("123","132"). 不

蓝桥杯 大臣的旅费_树的最长度_两次DFS

#include <iostream> #include <cstdio> #include <cstdlib> #include <algorithm> #include <cstring> #include <functional> #include <vector> using namespace std; const int maxn = 1000000 + 10; const int INF = 10000000

变形课(DFS hdu 1181)

变形课 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/65536 K (Java/Others)Total Submission(s): 19133    Accepted Submission(s): 6892 Problem Description 呃......变形课上Harry碰到了一点小麻烦,因为他并不像Hermione那样能够记住所有的咒语而随意的将一个棒球变成刺猬什么的,但是他发现了变形咒语的一个统一规