题意:给定花费上限d ,你有n 件物品,有m 件装饰品,每件物品和每件装饰品都有两个值攻击力图片说明 和花费图片说明 。一个物品最多被一个装饰品所装饰,每个装饰品不能独立存在,问在不超过花费上限的前提下,攻击力最大能到达多少.
购买限制:物品最多只能买五个.并且同一种商品不能重复购买.

分析:每种商品只能选购一次,那么就是01背包问题,状态的值就是当前ATK的最大值.

  • 根据数据范围开状态,我们可以让花费作为状态的第一维,题目限制买的物品数量不超过5个,购买物品的数量作为状态的第二维,并且装饰品与物品数量相关,购买装饰品的数量作为第三维。
  • 因为购买装饰品与购买物品唯一相关联的是数量,那么我们可以分两次背包,第一次背物品,第二次根据物品数量背装饰品。
  • 然后重新跑遍所有状态取最大值.
#include<bits/stdc++.h>
using namespace std;

const int maxn=10005;

int dp[140][6][6];

int main()
{
    int n,m,d;
    scanf("%d%d%d",&n,&m,&d);
    memset(dp,-0x3f,sizeof(dp));
    dp[0][0][0]=0;
    for( int i=1;i<=n;i++ )
    {
        int x,y;
        scanf("%d%d",&x,&y);
        for( int j=d;j>=y;j-- )
        {
            for( int k=1;k<=5;k++ )
            dp[j][k][0]=max(dp[j][k][0],dp[j-y][k-1][0]+x);    
        }
    }
    for( int i=1;i<=m;i++ )
    {
        int x,y;
        scanf("%d%d",&x,&y);
        for( int j=d;j>=y;j-- )
        {
            for( int k=1;k<=5;k++ )
            {
                for( int l=1;l<=k;l++ )
                dp[j][k][l]=max(dp[j][k][l],dp[j-y][k][l-1]+x);
            }
        }
    }
    int ans=-1;
    for( int i=0;i<=d;i++ )
    for( int j=0;j<=5;j++ )
    for( int k=0;k<=5;k++ ) ans=max(ans,dp[i][j][k]);
    printf("%d\n",ans);
}