题目链接
https://www.luogu.org/problemnew/show/P2967
题目大意
有
件平台,有
元钱,每件平台都有一定的代价,购买这个平台就可以获得某些游戏的使用权,但是要玩这些游戏还需要花费一定的代价,但也可以获得一定的价值
求不大于
元钱的最大价值
解题思路
这道题明显是金明的预算方案的加强版,对于多种情况我们需要分类讨论
1. 不选该平台
2. 选该平台
对于第二种操作,我们还需要再进行一次0/1背包
- 选该游戏
不选该游戏
所以,我们就得到了下面这些
设 表示前 个平台,花费了 元钱的最大价值,对于不选平台操作,我们可以少花 元钱,所以得到下面这个方程
对于选该平台操作,我们需要进行一波0/1背包,无非选或不选,得到下面方程
然后取这两种方案最大值即可
这样子做的空间消耗为 会爆炸,所以需要压缩数组,可以发现 只与 有关系,所以可以滚动压缩
代码
#include<cstdio>
using namespace std;int n,m,f[1000010],f2[1000010],gs,dj,num1,num2;
int main()
{
freopen("vidgame.in","r",stdin);
freopen("vidgame.out","w",stdout);
scanf("%d%d",&n,&m);
for (int i =0;i<n;++i)
{
scanf("%d %d",&dj, &gs);
for (int j=dj;j<=m;j++)f2[j]=f[j-dj];//不选该平台
for (int j=0;j<gs;++j)
{
scanf("%d%d",&num1,&num2);
for (int j=m-num1;j>=dj;j--) //选该平台
if (f2[j+num1]<f2[j]+num2) f2[j+num1]=f2[j]+num2;//选该游戏
}
for (int j=dj;j<=m;j++) if (f[j]<f2[j]) f[j]=f2[j];//保存最大值
}
printf("%d",f[m]);
}