动态规划练习(1)

#include<stdlib.h>
#include<stdio.h>
#define MAX 310
//http://blog.csdn.net/disappearedgod/article/details/8628975
int arr[MAX][MAX]; 

int main(){
    int i=1,j=1;
    int n =0;
    scanf("%d",&n);
    for(i=1;i <= n;i++){
       for(j=1; j<= i;j++){
           scanf("%d",&arr[i][j]);
           }
    }
    for(i=n;i>1;i--)
    { 
           for(j=0;j<=i-1;j++){               
               int a = arr[i][j]+ arr[i-1][j];
               int b = arr[i][j+1]+ arr[i-1][j]; 
               if(a>b)
                  arr[i-1][j]=a;
               else
                  arr[i-1][j]=b;
           }
    } 
    int res = arr[1][1];
    printf("%d",res);             
    
    //system("pause");
    return 0;
} 

转载请注明:From:http://blog.csdn.net/disappearedgod/article/details/8628975

例题:数字三角形(ai2760)

问题描述
7
3 8
8 1 0
2 7 4 4
4 5 2 6 5
上图给出了一个数字三角形。从三角形的顶部到底部有很多条不同的路径。对于每条路径,把路径上面的数加起来可以得到一个和,和最大的路径称为最佳路径。你的任务就是求出最佳路径上的数字之和。
注意:路径上的每一步只能从一个数走到下一层上和它最近的左边的数或者右边的数。输入数据
输入的第一行是一个整数N (1 < N <= 100),给出三角形的行数。下面的N 行给出数字三角形。数字三角形上的数的范围都在0 和100 之间。
输出要求
输出最大的和。
输入样例
5
7
3 8
8 1 0
2 7 4 4
4 5 2 6 5
输出样例
30
193


自己的想法:对于这样一个输入

   7                                  ---第一层

  |   \
  3    8                             ---第二层
  |  \ |  \ 

  8    1     0                      ---第三层

  |  \ |  \ |  \ 
  2    7    4     4               ---第四层

  |  \ |  \ |  \|  \  
  4    5    2   6    5           ---第五层

最开始的想法是从后面想到前面,我们选择的最佳路径是上一步的最佳加上现在。

对于迭代法来说,最多的是的想法是a1 = C; a (n)=f(a(n-1)) (n>1); 或者是a(n) = C, a(n-1)=f(a(n))(令n>0);我最先的想法是从an出发,当n==1时候返回值,每n-1的数是由第n层数的同一列(j)和下一列(j+1) 中的最大值产生的。

例如我们从第五层开始做

-------------------------------------------------分界线-----------------------------------------------------------

                                               7                                                   ---第一层

                                        /           \ 
                                 3                      8                                          ---第二层
                             /     \              /      \ 

                       8                     1                    0                               ---第三层

                  /             \       /        \          /       \ 
              2                    7                    4                   4                   ---第四层

        MAX(2+4/5) MAX(7+5/2) MAX(4+2/6) MAX(4+6/5)

     /            \         /        \           /       \           /            \  
  4                  5                    2                       6                   5          ---第五层

-------------------------------------------------分界线-----------------------------------------------------------

                                               7                                                     ---第一层

                                        /           \ 
                                 3                      8                                             ---第二层
                             /     \              /      \ 

                       8                     1                    0                                  ---第三层

                  /             \       /        \          /       \ 
              7                   12                    10                   10                   ---第四层

        MAX(2+4/5) MAX(7+5/2) MAX(4+2/6) MAX(4+6/5)

     /            \         /        \           /       \           /            \  
  4                  5                    2                       6                   5           ---第五层

-------------------------------------------------分界线-----------------------------------------------------------

                                               7                                                     ---第一层

                                        /           \ 
                                 3                      8                                             ---第二层

                             /     \              /      \ 

                      8                     1                    0                                  ---第三层

                 MAX(8+7/12)   MAX(1+12/10) MAX(0+10/10) 

                  /             \       /        \          /       \ 
              7                   12                    10                   10                    ---第四层

        MAX(2+4/5) MAX(7+5/2) MAX(4+2/6) MAX(4+6/5)

     /            \         /        \           /       \           /            \  
  4                  5                    2                       6                   5           ---第五层

-------------------------------------------------分界线-----------------------------------------------------------

                                               7                                                     ---第一层

                                        /           \ 
                                 3                      8                                             ---第二层

                             /     \              /      \ 

                       20                     13                   10                                  ---第三层

                 MAX(8+7/12)   MAX(1+12/10) MAX(0+10/10) 

                  /             \       /        \          /       \ 
              7                   12                    10                   10                    ---第四层

        MAX(2+4/5) MAX(7+5/2) MAX(4+2/6) MAX(4+6/5)

     /            \         /        \           /       \           /            \  
  4                  5                    2                       6                   5           ---第五层

-------------------------------------------------分界线-----------------------------------------------------------

                                             7                                                     ---第一层

                                        /           \ 
                                 3                      8                                             ---第二层

                       MAX(3+20/13)   MAX(8+13/10) 
                             /     \              /      \ 

                       20                     13                   10                                  ---第三层

                 MAX(8+7/12)   MAX(1+12/10) MAX(0+10/10) 

                  /             \       /        \          /       \ 
              7                   12                    10                   10                    ---第四层

        MAX(2+4/5) MAX(7+5/2) MAX(4+2/6) MAX(4+6/5)

     /            \         /        \           /       \           /            \  
  4                  5                    2                       6                   5           ---第五层

-------------------------------------------------分界线-----------------------------------------------------------

                                             7                                                     ---第一层

                                        /           \ 
                                 23                      31                                             ---第二层

                       MAX(3+20/13)   MAX(8+13/10) 
                             /     \              /      \ 

                       20                     13                   10                                  ---第三层

                 MAX(8+7/12)   MAX(1+12/10) MAX(0+10/10) 

                  /             \       /        \          /       \ 
              7                   12                    10                   10                    ---第四层

        MAX(2+4/5) MAX(7+5/2) MAX(4+2/6) MAX(4+6/5)

     /            \         /        \           /       \           /            \  
  4                  5                    2                       6                   5           ---第五层

-------------------------------------------------分界线-----------------------------------------------------------

                                              7                                                            ---第一层

                                MAX(7+23/31) 

                                        /           \ 
                                 23                      31                                             ---第二层

                       MAX(3+20/13)   MAX(8+13/10) 
                             /     \              /      \ 

                       20                     13                   10                                  ---第三层

                 MAX(8+7/12)   MAX(1+12/10) MAX(0+10/10) 

                  /             \       /        \          /       \ 
              7                   12                    10                   10                    ---第四层

        MAX(2+4/5) MAX(7+5/2) MAX(4+2/6) MAX(4+6/5)

     /            \         /        \           /       \           /            \  
  4                  5                    2                       6                   5           ---第五层

-------------------------------------------------分界线-----------------------------------------------------------

                                             38                                                            ---第一层

                                MAX(7+23/31) 

                                        /           \ 
                                 23                      31                                             ---第二层

                       MAX(3+20/13)   MAX(8+13/10) 
                             /     \              /      \ 

                       20                     13                   10                                  ---第三层

                 MAX(8+7/12)   MAX(1+12/10) MAX(0+10/10) 

                  /             \       /        \          /       \ 
              7                   12                    10                   10                    ---第四层

        MAX(2+4/5) MAX(7+5/2) MAX(4+2/6) MAX(4+6/5)

     /            \         /        \           /       \           /            \  
  4                  5                    2                       6                   5           ---第五层

-------------------------------------------------分界线-----------------------------------------------------------


#include<stdlib.h>
#include<stdio.h>
#define MAX 310

int BestChoise(int n,int arr[MAX][MAX]){
    //end
    int i = 0,j=0;
    for(i=n;i>0;i--)
        for(j=0;j<=i-1;j++){
            if(i == 1)
                return arr[1][1];  
            int a = arr[i][j]+ arr[i-1][j];
            int b = arr[i][j+1]+ arr[i-1][j]; 
            a>b? arr[i-1][j]=a:arr[i-1][j]=b;
        }
    
    //int a = BestChoise(i+1,j,n,arr);
    //int b = BestChoise(i+1,j+1,n,arr);
   // a>b? arr[i][j]+=a:arr[i][j]+=b;
}
int main(){
    int a[MAX][MAX];
    int i=1,j=1;
    int n =0;
    while(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;i++){
              for(j=1;j<=i;j++){                   
                   printf("%d  ",a[i][j]);
                   if(j==i)
                       printf("\n");
              }
        }
        */
        printf("%d",BestChoise(n,a));             
    }
    system("pause");
    return 0;
} 

状态:  Output Limit Exceeded

基本信息

题目:
2760
       内存:256kB
时间:
1970ms

-------------------------------------------------分界线-----------------------------------------------------------

看了一下解题思路

1.递归的本源思想
这道题目可以用递归的方法解决。基本思路是:
以D( r, j)表示第r 行第j 个数字(r,j 都从1 开始算),以MaxSum(r, j) 代表从第r 行
的第j 个数字到底边的最佳路径的数字之和,则本题是要求MaxSum(1, 1) 。
从某个D(r, j)出发,显然下一步只能走D(r+1, j)或者D(r+1, j+1)。如果走D(r+1, j),那
么得到的MaxSum(r, j)就是MaxSum(r+1, j) + D(r, j);如果走D(r+1, j+1),那么得到的MaxSum
(r, j)就是MaxSum(r+1, j+1) + D(r, j)。所以,选择往哪里走,就看MaxSum(r+1, j)和MaxSum

(r+1, j+1)哪个更大了。


对比于迭代法的代码

#include<stdlib.h>
#include<stdio.h>
#define MAX 310
int BestChoise(int i,int j,int n,int arr[MAX][MAX]){
    //end
    if(i == n)
    return arr[i][i];    
    
    //int a = arr[i+1][j]+ arr[i][j];
    //int b = arr[i+1][j+1]+ arr[i][j]; 
    //a>b? arr[i][j]=a:arr[i][j]=b;
    int a = BestChoise(i+1,j,n,arr);
    int b = BestChoise(i+1,j+1,n,arr);
    a>b? arr[i][j]+=a:arr[i][j]+=b;
    return arr[i][j];
}
int main(){
    int a[MAX][MAX];
    int i=1,j=1;
    int n =0;
    while(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;i++)
     //         for(j=1;j<=i;j++)
     //          printf("%d",BestChoise(1,1,n,a)); 
     printf("%d",BestChoise(1,1,n,a));             
    }
    system("pause");
    return 0;
} 

基本信息

#:
1891452
题目:
2760
提交人:
disappearedgod
内存:
256kB
时间:
1640ms
语言:
G++
提交时间:
2013-03-05 12:04:15

上述想法在时间复杂度上很大,递归改变成动态规划。而第一次的代码属于动态规划,但是仍然超时。

发现函数调用可以不用存在,并且最重要的是,while语句是多余的,因为没有说要多次输入。所以改成

#include<stdlib.h>
#include<stdio.h>
#define MAX 310
//http://blog.csdn.net/disappearedgod/article/details/8628975
int arr[MAX][MAX]; 

int main(){
    int i=1,j=1;
    int n =0;
    scanf("%d",&n);
    for(i=1;i <= n;i++){
       for(j=1; j<= i;j++){
           scanf("%d",&arr[i][j]);
           }
    }
    for(i=n;i>1;i--)
    { 
           for(j=0;j<=i-1;j++){               
               int a = arr[i][j]+ arr[i-1][j];
               int b = arr[i][j+1]+ arr[i-1][j]; 
               if(a>b)
                  arr[i-1][j]=a;
               else
                  arr[i-1][j]=b;
           }
    } 
    int res = arr[1][1];
    printf("%d",res);             
    
    //system("pause");
    return 0;
} 


-------------------------------------------------分界线-----------------------------------------------------------

注意

#include<stdlib.h>
#include<stdio.h>
#define MAX 310
//http://blog.csdn.net/disappearedgod/article/details/8628975
int arr[MAX][MAX]; 

int main(){
    //int a[MAX][MAX];
    int i=1,j=1;
    int n =0;
    scanf("%d",&n);
    for(i=1;i <= n;i++){
       for(j=1; j<= i;j++){
           scanf("%d",&arr[i][j]);
           }
    }
    for(i=n;i>1;i--)
    { 
           for(j=0;j<=i-1;j++){               
               int a = arr[i][j]+ arr[i-1][j];
               int b = arr[i][j+1]+ arr[i-1][j]; 
               a>b? arr[i-1][j]=a:arr[i-1][j]=b;
           }
       } 
        printf("%d",arr[1][1]);             
    
    //system("pause");
    return 0;
} 

这个代码中的:? 对于GCC编译器来讲是错的,报错为

error: lvalue required as left operand of assignment 

lvalue:左值是指可以被赋值的表达式。左值位于赋值语句的左侧与其相对的右值(rvaule)则位于赋值语句的右侧。
赋值语句都必须有一个左值和一个右值。左值必须是内存一个可存储的变量,而不能是一个常量。
所以,可以改成if else

if(a>b)
                  arr[i-1][j]=a;
               else
                  arr[i-1][j]=b;
           }



转载请注明:From:http://blog.csdn.net/disappearedgod/article/details/8628975

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值