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);
}