题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5234
解题思路:
DP题。类似于背包, Dp[i][j][k] 表示在第 (I,j) 个格子背包容量为 k 的时候的最大值。 Dp[i][j][k]=max(dp[i−1][j][k],dp[i][j−1][k],dp[i−1][j][k−w[i][j]]+w[i][j],dp[i][j−1][k−w[i][j]]+w[i][j]); 初值所有均为 0 。 答案取 max(dp[n][m][i]) for 0≤i≤C , C 为最大容量。 总状态是 n∗m∗k ,转移 o(1) 最后复杂度是 n∗m∗k
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> using namespace std; int a[110][110]; int dp[110][110][110]; int main() { int n,m,k; while(scanf("%d%d%d",&n,&m,&k)!=EOF) { int i,j,ans,sum = 0; for(i = 1; i <= n; i++) for(j = 1; j <= m; j++) scanf("%d",&a[i][j]); memset(dp,0,sizeof(dp)); for(i = 1; i <= n; i++) { for(j = 1; j <= m; j++) { for(ans = 0; ans <= k; ans++) { if(ans < a[i][j]) dp[i][j][ans] = max(dp[i-1][j][ans],dp[i][j-1][ans]); else dp[i][j][ans] = max(max(dp[i-1][j][ans-a[i][j]],dp[i][j-1][ans-a[i][j]])+a[i][j],max(dp[i-1][j][ans],dp[i][j-1][ans])); //当ans < a[i][j]也可以不取,所以要加上max(dp[i-1][j][ans],dp[i][j-1][ans]) } } } for(i = 1; i <= m; i++) sum = max(sum,dp[n][i][k]); printf("%d\n",sum); } return 0; }