三角形问题:dfs的一个弊端。

有一个三角形数阵,行数和列数相等,第n行有n个数字,现在从上顶点,也就是第一行第一列出发,只能向左下或者向右下走到下一行,一直走到末尾,求怎么能使路径上的数字和最大,求这个最大值。

第一行是一个数m,代表测试次数;对于每一次测试:第一行是一个数n(1<n<100),代表这个三角形数阵有n行,接着是n行的一个三角形数阵(对于每一个数都有1<Aij<100)。

例如:输入:

1

5

7

3   8

8   1   0

2   7   4   4

4   5   2   6   5

输出:

30

对于这个问题,很容易想到用dfs,一条路径一条路径的找下去,最后得到那个最大值,所以写出了以下的程序:

#include<stdio.h>
int a[100][100]={0},i,j,k,m,n;
int max=0,ans;
void dfs(int x,int y, int ans)
{
    ans+=a[x][y];
    if(x==n-1)
    {
        if(max<ans)
        max=ans;
    }
    else
    {
        dfs(x+1,y,ans);
        dfs(x+1,y+1,ans);
    }
}
main()
{
    scanf("%d",&m);
    while(m--)
    {
        scanf("%d",&n);
        for(i=0;i<n;i++)
        {
            for(j=0;j<=i;j++)
           {
                scanf("%d",&a[i][j]);
           }
        }
        dfs(0,0,0);
        printf("%d\n",max);
     }
}

然后带入样例,发现是对的,但是,忽略了一点:时间。对,如果测试一个有99行的样例,那么会发现结果会弹出的非常慢,为什么呢?

用数学方法算算就会知道:99行的样例一共会有2的98次方个路径,这么多路径,对于计算机来说也是较为庞大的,更何况要去找那个最大值,

就更不容易了!

那怎么去做这个题呢?既然要找最大值,那肯定走到每一个位置都有一个最大值,从头去找那个最大值不好找那何不直接从最后一行退回去找呢?

除了存放数阵的数组外,再定义一个数组,同样有n行,但是每个位置存放着倒着走走到当前的最大值,这样一层一层往上,这个数组的第一行的那个数

肯定就是所有路径的最大值了;

例如:

对于:

7                        的路径最大值数阵为:     30

3   8                                                    23       21

8   1   0                                               20        13       10

2   7   4   4                                           7         12       10       10

4   5   2   6   5                                      4          5         2        6        5

用这个思路,很容易就写出了以下的程序:

#include<stdio.h>
int a[100][100]={0},b[100][100],i,j,k,m,n;
int max(int x,int y)
{
    if(x>y)
    return x;
    else
    return y;
}
void d(int n)
{
    for(i=0;i<n;i++)
        b[n-1][i]=a[n-1][i];
    for(i=n-2;i>=0;i--)
    {
        for(j=i;j>=0;j--)
        b[i][j]=a[i][j]+max(b[i+1][j],b[i+1][j+1]);
     }
}
main()
{
    scanf("%d",&m);
    while(m--)
    {
    scanf("%d",&n);
    for(i=0;i<n;i++)
    {
        for(j=0;j<=i;j++)
        {
            scanf("%d",&a[i][j]);
        }
     }
     d(n);
    printf("%d\n",b[0][0]);
    }
}

可以看到,对于这个程序,即使有100行,也只需要运算4950次,将数组   b    填满,就可以得到答案。多用dfs就会发现,

用dfs很容易时间超限,这时候,就需要用其他算法将其代替,所以,最好是在一开始就决定是否要用dfs,以免浪费时间!!

时间: 2024-11-05 01:53:21

三角形问题:dfs的一个弊端。的相关文章

nyoj 491 幸运三角形 【DFS】+【打表】

幸运三角形 时间限制:1000 ms  |  内存限制:65535 KB 难度:3 描述 话说有这么一个图形,只有两种符号组成('+'或者'-'),图形的最上层有n个符号,往下个数依次减一,形成倒置的金字塔形状,除第一层外(第一层为所有可能情况),每层形状都由上层决定,相邻的符号相同,则下层的符号为'+',反之,为'-';如下图所示(n = 3 时的两种情况): 如果图中的两种符号个数相同,那这个三角形就是幸运三角形,如上图中的图(2). 输入 有多组测试数据(少于20组). 每行含一个整数n(

nyoj 491 幸运三角形 (dfs + 打表 出现木马 哈哈)

题目491 题目信息 运行结果 本题排行 讨论区 幸运三角形 时间限制:1000 ms  |  内存限制:65535 KB 难度:3 描述 话说有这么一个图形,只有两种符号组成('+'或者'-'),图形的最上层有n个符号,往下个数依次减一,形成倒置的金字塔形状,除第一层外(第一层为所有可能情况),每层形状都由上层决定,相邻的符号相同,则下层的符号为'+',反之,为'-';如下图所示(n = 3 时的两种情况): 如果图中的两种符号个数相同,那这个三角形就是幸运三角形,如上图中的图(2). 输入

hdu 1455 Sticks DFS 又是一个花样剪枝 ,累觉不爱

Sticks Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 6750    Accepted Submission(s): 1967 Problem Description George took sticks of the same length and cut them randomly until all parts becam

基于Qt的OpenGL可编程管线学习(1)- 绘制一个三角形

0.写在前面的话 这里只是学习的时候做的笔记记录方便日后的查看,如果有大神看到觉得有问题的地方希望能给予指出,方便日后的学习,谢谢! 我是用的Qt版本为Qt5.6,开发环境为Qt Creator 1.QOpenGLWidget 在Qt开发环境下,使用OpenGL的可编程管线绘制一个三角形 效果如下图所示: 这里使用QOpenGLWidget进行绘制的,在QOpenGLWidget中需要重写 void initializeGL(void); void resizeGL(int w, int h);

directx学习之在屏幕上画一个三角形

前一张已经输出了一个背景为紫色的屏幕,这一节的目标是在该屏幕上输出一个三角形.下面将逐一介绍建立一个三角形的过程. 一个三角形有三个点,叫做顶点.三个点的不同的集合可以建立不同的三角形.能让GPU创建一个三角形,必须将三个顶点的位置告诉它.下面是一个2D的例子. 怎么将三个点的数据传给GPU? 在d3d10中,顶点数据被存在一个缓存资源中.但是应该申请多大的缓存,这就是接下来的问题. 一个顶点就是一个位置,通常也包含一些其他的属性,比如颜色,纹理协调等.顶点结构就定义了那些属性在内存中的位置.

Effective前端1---chapter 2 用CSS画一个三角形

1.CSS画三角形的画法 第一步:三角形可以用border画出来,首先一个有四个border的div长这样: <div class="triangle"></div> <style> .triangle{ margin: 100px; border-top: 40px solid #000; border-bottom: 40px solid #333; border-left: 40px solid #666; border-right: 40px

编程:判断一个点是否在三角形内部

题目描述: 在二维坐标系中,所有的值都是double类型,那么一个三角形可以由3个点来代表,给定3个点代表的三角形,再给定一个点(x, y),判断(x, y)是否在三角形中 题目分析: 方法1:面积法:如果点(x, y)在三角形内部,那么三个小三角形的面积相加等于大三角形面积. 注意:已知三角形三个点,求三角形面积. 方法2:向量法:如果点(x, y)在三角形内部,那么从某个点逆时针出发,点(x, y)都在每条边的左侧. 注意:判断一个点在一个有向边的左侧还是右侧. #include<iostr

[ZOJ 1008]Gnome Tetravex (dfs搜索 + 小优化)

题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=1008 题目大意:给你n*n的矩阵,每个格子里有4个三角形,分别是上右下左,每个三角形里面标记了数字,问你能否通过移动这n*n个格子,使得相邻两个三角形具有相同的数字? dfs暴搜,dfs(x,y)代表当前要放(x,y)这个位置. 然后枚举给定的每个格子. 如果说可以放,就dfs下一个格子. 这一道题需要把相同的格子压缩起来,也就是说为了节省时间,可以记录相同的格

算法设计与分析 2.2 画三角形

★题目描述 编程画出规模为N的三角形. 规模为1的三角形如样例所示. 规模为X的三角形为三个规模为 X-1的三角形拼接而成,如样例所示. ★输入格式 一个整数N,表示三角形的规模. 对于100%的数据,1 <= N <= 10. ★输出格式 画出对应的三角形,注意最后一个有效字符后直接回车,不要输出多余的空格. ★样例输入1 1 ★样例输出1 //__\ ★样例输入2 2 ★样例输出2 / /__ /\ //__\/__\ ★提示 /* 3 /\ 0 /__\ 1 /\ /\ 2 /__\/_