Description
给定一摞扑克牌,共 \(n \le 1000\) 张,每张牌有两个属性 \(a_i,b_i \le 1000\)。可以无限次进行以下两种操作:①对于堆顶的牌 \((a,b)\),从上到下扔掉 \(a\) 张牌,得分 \(+b\);②将牌堆顶的牌放到底部。求能获得的最大得分。
Solution
连续拿走若干张牌的条件,和随意拿走若干张牌,其实是等价的。
证明:反证法,考虑不等价,即连续拿走 \(x\) 时必须拿走 \(y\),但是 \(y\) 是想要另拿的。此时若我们可以先把 \(y\) 拿掉则矛盾。若我们不可以先拿走 \(y\),那么一定有 \(a_x+a_y >n\),则此时不可能在不连续情况下另拿 \(y\),故矛盾。
于是问题转化为,总空间为 \(n\) 的背包,每种物品占用空间 \(a_i\),价值为 \(b_i\),求最大价值。
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N = 1005;
int n,a[N],b[N],f[N];
signed main()
{
ios::sync_with_stdio(false);
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>a[i]>>b[i];
}
for(int i=1;i<=n;i++)
{
for(int j=n;j>=a[i];j--)
{
f[j]=max(f[j],f[j-a[i]]+b[i]);
}
}
cout<<*max_element(f,f+n+1);
}