p1044 p1076 p1079 p1084 数字三角形系列 小结

FIRST

一、本例:
示出了一个数字三角形。 请编一个程序计算从顶至底的某处的一条路径,使该路径所经过的数字的总和最大。
 每一步可沿左斜线向下或右斜线向下走;
 1<三角形行数<25;
 三角形中的数字为整数<1000;

5
7
3 8
8 1 0
2 7 4 4
4 5 2 6 5

二、分析:
不解释,最基本动归。f[i][j]=f[i][j]+max(f[i+1][j],f[i+1][j+1]),这是从下到上的方法,最终答案是f[i][j]的。


三、代码:

# include "stdio.h"
int max(int a,int b)
{
    if (a>b) return a;
    return b;
}
int main()
{
    int a[30][30]={0},i,j,n;
    scanf("%d",&n);
    for(i=1;i<=n;i++)
       for(j=1;j<=i;j++)
          scanf("%d",&a[i][j]);
    
    for(i=n;i>1;i--)
       for(j=1;j<=i;j++)
          a[i-1][j]+=max(a[i][j],a[i][j+1]);
          
    printf("%d",a[1][1]);
    return 0;
}

四.分析、
额,这个..应该有种很源头的感觉..有些合并,的感觉,就叫路线类动归吧

SECEND

一、题目变式、

数字三角形
要求走到最后mod 100最大

二、分析.
还是差一些..看着没感觉,但是自己清楚,任何取最大的步骤,必然错。肯定要记录下所有的过程。然后想到守望者逃离这个题,一想,可以用逻辑数组,记录下来..于是乎,就有了思路,开敲。

三、代码、

# include "stdio.h"
int a[30][30]={0},f[30][30][110]={0};
int main()
{
    int  i,j,k,n,tem,max=-1;
   
    scanf("%d",&n);
        
    for(i=1;i<=n;i++)
       for(j=1;j<=i;j++)    
         scanf("%d",&a[i][j]);
    
    f[1][1][(a[1][1])%100]=1;        
         
    for(i=2;i<=n;i++)
       for(j=1;j<=i;j++)           
         for(k=0;k<=99;k++)
            {
            if (f[i-1][j][k]==1 || f[i-1][j-1][k]==1) f[i][j][(a[i][j]+k)%100]=1;
            }            
  
    for(j=1;j<=n;j++) 
       for(k=0;k<=99;k++)
          if (f[n][j][k]==1 && k>max) max=k;
          
    printf("%d",max);
             
    return 0;
}

四、错误分析;
1.题目不难,可以说是水了。但是,还是翻了个错误,结合了守望者的特点,所有的上一层真值,都来判断,这就不符合题意了。所以结果可能会错..虽然第一次居然过了9个点,说明数据极其不给力!!!所以,再加一维,以分离状态。还好发现了这个小漏洞,再一次说明,每个题都是不一样的。
2.定义数组的时候,刚开始是30*110,后来需要一个30*30*110的,显然可以算是一个大叔组了,但是自己却没有定义到main外头..导致编译过不去,wa了一次...以后养成习惯,数组,全局变量全放外头

THIRD
一、题目变式、

数字三角形
程序必须经过n div 2,n div 2这个点,使之走的路程和最大

二、思路分析:
刚开始没有理解题目的意思,可以说是会错意了,这个题,可以先找到从(1,1)点,到(n/2,n/2)的最大值,然后加上从(n/2,n/2)到(n,n)的最大值就可以了

三、代码:

# include "stdio.h"
int max(int a,int b)
{
    if (a>b) return a;
    return b;
}
int main()
{

    int a[30][30]={0},i,j,n,ans=0;
    scanf("%d",&n);
    for(i=1;i<=n;i++)
       for(j=1;j<=i;j++)
          scanf("%d",&a[i][j]);
    
    for(i=1;i<n/2;i++) ans+=a[i][i];

    for(i=n;i>n/2;i--)
       for(j=n/2;j<=i;j++)
            a[i-1][j]+=max(a[i][j],a[i][j+1]);
    
    ans+=a[n/2][n/2];   
    printf("%d",ans);
  
    return 0;
}

四、认识:
这个题,因为没有理解正确wa了两次...还是集中注意力,专心做题

FOURTH
一、题目变式、

数字三角形
程序必须经过(x,y)2这个点,使之走的路程和最大

二、分析:
这回的问题,是三的一个全集,补充,三只是一个特例。所以,四做出来,三更能做出来。一样的思路,最大值来自从(1,1)点,到(x,y)的最大值,加上,从(x,y)走到底的最大值。

三、代码:

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


四、错误认识:
1.这题编出来,应该是要比较清楚的一个图在脑子里,边界非常清楚才行。
2.为了集中答案。可以把最大值放到接近的地方.
3.a[i][j],i是行数,j是列数,应该清清楚楚的

你可能感兴趣的:(算法,ACM)