看到这题其实感觉就是搜索题,广搜的话看讨论区里已经有人内存超限了,所以我选择了深搜,有两种思路,第一种是从起点出发,依次更新每一个格子的最大值,这样dp[n][m]就是最后的结果了,第二种是从起点试探到终点,回溯时带回最大值,这样dp[1][1]就是最大值了。
思路1 187MS
#include<iostream> #include<cstring> #include<cstdio> using namespace std; const int N = 1000 + 5; const int INF = -(1<<30); int mat[25][N],dp[25][N],n,m; bool visit[25][N]; void DFS(int x, int y, int sum){ sum += mat[x][y]; if(sum < dp[x][y]) return; if(sum > dp[x][y]) dp[x][y] = sum; if(x+1 <= n) DFS(x+1, y, sum); if(y+1 <= m) DFS(x, y+1, sum); for(int i=2; y*i <= m ;i++) DFS(x, y*i, sum); } void Init_mat(){ for(int i=0;i<=n;i++) for(int j=0;j<=m;j++) visit[i][j] = false, dp[i][j] = INF; } int main(){ int T; scanf("%d",&T); while(T--){ scanf("%d %d",&n,&m); Init_mat(); for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) scanf("%d",&mat[i][j]); DFS(1,1,0); printf("%d ",dp[n][m]); } }
思路2 31MS
#include<iostream> #include<cstring> #include<cstdio> using namespace std; const int N = 1000 + 5; const int INF = -(1<<30); int mat[25][N],dp[25][N],n,m; bool visit[25][N]; void DFS(int x, int y, int sum){ sum += mat[x][y]; if(sum < dp[x][y]) return; if(sum > dp[x][y]) dp[x][y] = sum; if(x+1 <= n) DFS(x+1, y, sum); if(y+1 <= m) DFS(x, y+1, sum); for(int i=2; y*i <= m ;i++) DFS(x, y*i, sum); } void Init_mat(){ for(int i=0;i<=n;i++) for(int j=0;j<=m;j++) visit[i][j] = false, dp[i][j] = INF; } int main(){ int T; scanf("%d",&T); while(T--){ scanf("%d %d",&n,&m); Init_mat(); for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) scanf("%d",&mat[i][j]); DFS(1,1,0); printf("%d ",dp[n][m]); } }
其实这题还有个插图来着>_<,在这了