题意:给一个nXm的矩阵,上面有一些数字,从左上角出发,每次只能往右或者往下,把沿途的数字加起来,求到达右下角的最大值是多少。
题解:简单的一个dp,设f[i][j]为到达i行j列的最大值,f[i][j] = max(f[i-1][j],f[i][j-1])+a[i][j],然后用队列刷表法。
#include<cstdio> #include<cstring> #include<queue> using namespace std; typedef long long ll; //#define local #define fi first #define se second const int maxn = 1005; int f[maxn][maxn]; int a[maxn][maxn]; int main() { int T; scanf("%d",&T); for(int k = 1; k <= T; k++) { int n,m; scanf("%d%d",&n,&m); for(int i = 0; i < n; i++){ for(int j = 0; j < m; j++){ scanf("%d",a[i]+j); } } queue< pair<int,int> > q; memset(f,0x80,sizeof(f)); q.push(make_pair(0,0)); f[0][0] = a[0][0]; while(q.size()){ pair<int,int> &u = q.front(); int r = u.fi, c = u.se; if(r<n && f[r+1][c]<f[r][c]+a[r+1][c]) f[r+1][c] = f[r][c]+a[r+1][c],q.push(make_pair(r+1,c)); if(c<m && f[r][c+1]<f[r][c]+a[r][c+1]) f[r][c+1] = f[r][c]+a[r][c+1],q.push(make_pair(r,c+1)); q.pop(); } printf("Case %d: %d ",k,f[n-1][m-1]); } return 0; }