题解思路:
n*m的两次背包,时间复杂度O(n*m*k),dp[i][j][t]表示到i,j做个位置容量最大为t能装多少,理解之后就是01背包问题。
代码:
#include<bits/stdc++.h>
using namespace std;
const int mx = 1e2+2;
int n,m,k;
int maps[mx][mx],dp[mx][mx][mx];
void right(int i,int j){
for(int t=1;t<=k;t++) dp[i][j][t] = max(dp[i][j][t],dp[i][j-1][t]);
for(int t=k;t>=maps[i][j];t--)
dp[i][j][t] = max(dp[i][j][t],dp[i][j-1][t-maps[i][j]]+maps[i][j]);
}
void down(int i,int j){
for(int t=1;t<=k;t++) dp[i][j][t] = max(dp[i][j][t],dp[i-1][j][t]);
for(int t=k;t>=maps[i][j];t--)
dp[i][j][t] = max(dp[i][j][t],dp[i-1][j][t-maps[i][j]]+maps[i][j]);
}
int main()
{
while(~scanf("%d%d%d",&n,&m,&k)){
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++) scanf("%d",maps[i]+j);
for(int i=1;i<=k;i++) dp[1][1][i] = i<maps[1][1]? 0:maps[1][1];
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
if(i==1&&j==1) continue;
for(int t=1;t<=k;t++) dp[i][j][t] = 0;
if(j!=1) right(i,j);
if(i!=1) down(i,j);
}
}
printf("%d\n",dp[n][m][k]);
}
return 0;
}