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代码中写出来应该是递推的写法:
View Code
状态转移: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 ",dp[n][m]); 38 } 39 return 0; 40 }