dp最大路径和,注意初始化,HDU

http://acm.hdu.edu.cn/showproblem.php?pid=2571

简单dp题目,推算最大的路径和:

状态:f[i][j]:从第[i,j]到终点的最大值
状态转移:f[i][j]=max{f[i+1][j],f[i][j+1],f[i][j*k](k>1)}
初始值:f[n][m]=a[n][m];
这是递归的思想,而在dp代码中写出来应该是递推的写法:
状态转移:f[i][j]=a[i][j]+max{f[i-1][j],f[i][j-1],f[i][j/k](k>1)}
这题关键应该在于初始化,为了保证第一行和第一列保留的都是他们原本的数字,可以在二维矩阵外面再多加一圈负无穷的数,特别的为保证第一个,应该吧第一个的上面和左边都赋为0,这样可以保证f[1][1]=a[1][1]
 1 #include<stdio.h>
 2 #include<string.h>
 3 int max(int a,int b)
 4 {
 5     return a>b?a:b;
 6 }
 7 int dp[21][1001];
 8 int main()
 9 {
10     int n,m,i,j,k,c,f,s[21][1001];
11     scanf("%d",&c);
12     while(c--)
13     {
14       //memset(dp,0,sizeof(dp));
15       scanf("%d%d",&n,&m);
16       for(i=1;i<=n;i++)
17        for(j=1;j<=m;j++)
18       scanf("%d",&s[i][j]);
19       
20       for(i=0;i<=n;i++)
21         dp[i][0]=-999999;//边缘初始化
22       for(i=0;i<=m;i++)
23         dp[0][i]=-999999;//边缘初始化,这里的初始化是为了第一行和第一列不会越界 
24       dp[1][0]=dp[0][1]=0;//这里当i==1&&j==1时,i-1==0;j-1==0,所以会保留dp[1][0],dp[0][1]中最大,然后加上本身,这样做可以保证dp[1][1]=s[1][1] 
25       
26       for(i=1;i<=n;i++)
27         for(j=1;j<=m;j++)
28         {
29           f=-999999;//赋为无穷小 
30            for(k=2;k<=j;k++)
31            {
32              if(j%k==0)
33               f=max(f,dp[i][j/k]);//如果有更大的,就保留更大的 
34            }
35            dp[i][j]=max(max(dp[i-1][j],dp[i][j-1]),f)+s[i][j];;
36         }
37       printf("%d\n",dp[n][m]);
38     }
39     return 0;
40 }
View Code

 

posted @ 2013-08-07 21:29  执着追求的IT小小鸟  阅读(250)  评论(0编辑  收藏  举报