HDU 5234 Happy birthday --- 三维01背包

 

  HDU 5234

  题目大意:给定n,m,k,以及n*m(n行m列)个数,k为背包容量,从(1,1)开始只能往下走或往右走,求到达(m,n)时能获得的最大价值

  解题思路:dp[i][j][k]表示在位置(i,j)有一个容量为k的背包所能获得的最大价值

       决策:a[i][j]处的数是否选取

       不选取: dp[i][j][k]= max(dp[i-1][j][k], dp[i][j-1][k])

       选取:首先要求k >=a[i][j],那么dp[i][j][k] = max(dp[i-1][j][k-w[i][j]], dp[i][j-1][k-w[i][j]]);

       相当于求四者的最大值,最后dp[m][n][k]即为所求结果

/* HDU 5234 Happy birthday --- 三维01背包 */
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;

const int maxn = 105;
int w[maxn][maxn];
int dp[maxn][maxn][maxn];
int n, m, V;

int main()
{
#ifdef _LOCAL
    freopen("D:\\input.txt", "r", stdin);
#endif

    //n行m列容量为V
    while (scanf("%d%d%d", &n, &m, &V) == 3){
        for (int i = 1; i <= n; ++i){
            for (int j = 1; j <= m; ++j){
                scanf("%d", w[i] + j);
            }//for(j)
        }//for(i)

        memset(dp, 0, sizeof dp);

        for (int i = 1; i <= n; ++i){
            for (int j = 1; j <= m; ++j){
                for (int k = 0; k <= V; ++k){
                    //w[i][j]不取的时候
                    int a = max(dp[i - 1][j][k], dp[i][j - 1][k]);
                    int b = 0;
                    //k > w[i][j], w[i][j]取的时候
                    if (k - w[i][j] >= 0){
                        b = max(dp[i - 1][j][k - w[i][j]], dp[i][j - 1][k - w[i][j]]) + w[i][j];
                    }
                    dp[i][j][k] = max(a, b);
                }
            }//for(j)
        }//for(i)

        printf("%d\n", dp[n][m][V]);
    }

    return 0;
}
View Code

 

posted @ 2016-04-06 02:15  tan90丶  阅读(237)  评论(0编辑  收藏  举报