题目地址:点击打开链接
思路:简单DP,但是有很多需要注意的地方,首先DP数组不能初始化为0,因为DP保存的是这个点能取得的最大幸运值,可能为0,应该初始化为一个很小的负数,第二个就是保存值时i,j要从1开始循环,因为走的是列的倍数
错误代码:
#include <iostream> #include <cstring> #include <cstdio> using namespace std; int a[21][1001],dp[21][1001]; int n,m; const int MAX = -200000000; int dfs(int x,int y) { int i,max1 = MAX; if(dp[x][y] != MAX) return dp[x][y]; if(x+1 < n) max1 = dfs(x+1,y); if(y+1 < m && dfs(x,y+1) > max1) { max1 = dfs(x,y+1); } for(i=2; i*y<m; i++)//直接在这死循环了 { if(i*y < m && dfs(x,i*y) > max1) max1 = dfs(x,i*y); } dp[x][y] = a[x][y] + max1; return dp[x][y]; } int main() { int t,i,j; scanf("%d",&t); while(t--) { scanf("%d%d",&n,&m); for(i=0; i<n; i++) { for(j=0; j<m; j++) { scanf("%d",&a[i][j]); dp[i][j] = MAX; } } dp[n-1][m-1] = a[n-1][m-1]; printf("%d\n",dfs(0,0)); } return 0; }
#include <iostream> #include <cstring> #include <cstdio> using namespace std; int a[21][1001],dp[21][1001]; int n,m; const int MAX = -200000000; int dfs(int x,int y) { int i,max1 = MAX; if(dp[x][y] != MAX) return dp[x][y]; if(x+1 <= n) max1 = dfs(x+1,y); if(y+1 <= m && dfs(x,y+1) > max1) { max1 = dfs(x,y+1); } for(i=2; i*y<=m; i++) { if(i*y < m && dfs(x,i*y) > max1) max1 = dfs(x,i*y); } dp[x][y] = a[x][y] + max1; return dp[x][y]; } int main() { int t,i,j; scanf("%d",&t); while(t--) { scanf("%d%d",&n,&m); for(i=1; i<=n; i++) { for(j=1; j<=m; j++) { scanf("%d",&a[i][j]); dp[i][j] = MAX; } } dp[n][m] = a[n][m]; printf("%d\n",dfs(1,1)); } return 0; }AC代码:
#include <iostream> #include <cstring> #include <cstdio> using namespace std; int a[21][1001],dp[21][1001]; const int MAX = -200000000; int main() { int t,i,j,k,n,m; scanf("%d",&t); while(t--) { scanf("%d%d",&n,&m); for(i=1; i<=n; i++) { for(j=1; j<=m; j++) { scanf("%d",&a[i][j]); } } for(i=0; i<=n; i++)//处理第一列的特殊情况,在求DP值函数里面分类讨论比较麻烦,就把特殊行和列处理一下 { dp[i][0] = MAX; } for(i=0; i<=m; i++)//处理第一行的特殊情况 { dp[0][i] = MAX; } dp[0][1] = 0; dp[1][0] = 0;//处理第一个值得特殊情况, for(i=1; i<=n; i++) { for(j=1; j<=m; j++) { dp[i][j] = max(dp[i-1][j],dp[i][j-1]); for(k=2; k<=m; k++) { if(j % k == 0) dp[i][j] = max(dp[i][j],dp[i][j/k]); } dp[i][j] += a[i][j]; } } printf("%d\n",dp[n][m]); } return 0; }