题意:给定花费上限 ,你有
件物品,有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);
}

京公网安备 11010502036488号