bzoj 4247: 挂饰【dp】
bzoj上访问负下标会跑到奇怪的地方……
其实可以滚动数组优化,但是我看能过就懒得改了
设f[i][j]为已经算了前i个挂饰,当前有j个空的钩子,转移就是f[i][j]=max(f[i-1][j],f[i-1][max(min(j-a[i]+1,n),-n)]+b[i])
注意到只有-n<=j<=n的范围内j是有用的,所以时空都是n^2的,负的j算的时候直接+n即可
#include<iostream>
#include<cstdio>
using namespace std;
const int N=4005;
int n,a[N],b[N],f[N][N],ans;
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%d%d",&a[i],&b[i]);
for(int i=2;i<=n;i++)
f[0][i+n]=-2e9;
for(int i=1;i<=n;i++)
for(int j=-n;j<=n;j++)
f[i][j+n]=max(f[i-1][j+n],f[i-1][max(min(j-a[i]+1,n),-n)+n]+b[i]);
for(int i=0;i<=n;i++)
ans=max(ans,f[n][i+n]);
printf("%d\n",ans);
return 0;
}