题意:给一个n*m的矩阵,每个点是一个蛋糕的的重量,然后小明只能向右,向下走,求在不超过K千克的情况下,小明最终能吃得最大重量的蛋糕。
思路:类似背包DP;
状态转移方程:dp[i][j][k]----在i,j位置时,最大容量为k时的最大值;
做背包循环一般从1开始,因为需要坐标-1的情况,从0开始需要特判,而且容易RE;
1 #include <iostream> 2 #include <cmath> 3 #include <cstdio> 4 #include <cstring> 5 #include <cstdlib> 6 #include <string> 7 #include <sstream> 8 #include <algorithm> 9 #define Max 2147483647 10 #define INF 0x7fffffff 11 #define N 110 12 #define ll long long 13 #define mem(a,b) memset(a,b,sizeof(a)) 14 #define repu(i, a, b) for(int i = (a); i < (b); i++) 15 const double PI=-acos(-1.0); 16 using namespace std; 17 int dp[N][N][N]; 18 int w[N][N]; 19 int main() 20 { 21 int n,m,k; 22 while(~scanf("%d%d%d",&n,&m,&k)) 23 { 24 repu(i,0,1+n) 25 repu(j,0,m+1) 26 repu(p,0,k+1) 27 dp[i][j][p] = 0; 28 repu(i,1,1+n) 29 repu(j,1,1+m) 30 scanf("%d",&w[i][j]); 31 repu(i,1,n+1) 32 { 33 repu(j,1,m+1) 34 { 35 for(int p = w[i][j]; p<=k; p++) 36 { 37 int t = max(dp[i-1][j][p],dp[i][j-1][p]);///左边,上边 38 int s = max(dp[i-1][j][p-w[i][j]]+w[i][j],dp[i][j-1][p-w[i][j]]+w[i][j]); 39 dp[i][j][p] = max(t,s); 40 } 41 } 42 } 43 int maxn = 0; 44 repu(p,0,k+1) 45 maxn = max(dp[n][m][p],maxn); 46 printf("%d\n",maxn); 47 } 48 return 0; 49 }
背包
时间: 2024-10-20 22:52:17