HDU-3127 完全背包

链接:点击打开链接

有一个很大的矩形,给你一些小矩形及其价值,要求能获得的最大价值。

dp【x】【y】表示x,y的矩形能得到的最大价值。


首先矩形可以正着放有两种方法,

要求 i>y&&j>x

z+max ( dp[i][j-y]+dp[i-x][y],dp[x][j-y]+dp[i-x][j] )

取两者的最大值加上这个小矩形的价值。

也可以竖着放两种方法。

由于懒得想dp的下标,所以直接交换了一下 x和y,然后就变成和第一种一样了。

swap(x,y);

要求 i>y&&j>x

z+max ( dp[i][j-y]+dp[i-x][y],dp[x][j-y]+dp[i-x][j] )

最后就是循环的循序,先 i和j 最后再枚举小矩阵。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#include<algorithm>
#include<vector>
#include<map>
#include<cmath>
using namespace std;
typedef long long LL;
const int maxn=1e5+5;
int dp[1010][1010];
int x[12],y[12],z[12];
int main()
{
    int T,n,X,Y;
    scanf( "%d", &T );
    while ( T-- )
    {
        scanf( "%d%d%d", &n, &X ,&Y );
        for(int i=0;i<n;i++) scanf( "%d%d%d", &x[i], &y[i], &z[i] );
        memset(dp,0,sizeof(dp) );
        for(int i=0;i<=X;i++)
            for(int j=0;j<=Y;j++)
        {
            for(int k=0;k<n;k++)
            {
                if(i>=x[k]&&j>=y[k])
                    dp[i][j]=max(dp[i][j],z[k]+max(dp[i][j-y[k]]+dp[i-x[k]][y[k]],dp[x[k]][j-y[k]]+dp[i-x[k]][j]));
                swap(x[k],y[k]);
                if(i>=x[k]&&j>=y[k])
                    dp[i][j]=max(dp[i][j],z[k]+max(dp[i][j-y[k]]+dp[i-x[k]][y[k]],dp[x[k]][j-y[k]]+dp[i-x[k]][j]));
            }
        }
        printf( "%d\n", dp[X][Y] );
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_41713256/article/details/80782998
今日推荐