单调队列优化dp
一题思维好题
就是有3个转移方程
初始化:
容易观察到第二个和第三个可以用单调队列优化
于是就做完了
#include <bits/stdc++.h>
#define il inline
#define Max 2005
using namespace std;
il int read()
{
char c=getchar();
int x=0,f=1;
while(c>'9'||c<'0')
{
if(c=='-') f=-1;
c=getchar();
}
while(c>='0'&&c<='9')
{
x=x*10+c-'0';
c=getchar();
}
return x*f;
}
int n,m,w;
int f[Max][Max],ap,bp,as,bs,q[Max],ans;
int main()
{
memset(f,128,sizeof(f));
n=read(),m=read(),w=read();
for(int i=1;i<=n;i++)
{
ap=read(),bp=read(),as=read(),bs=read();
for(int j=0;j<=as;j++)
f[i][j]=-1*(j)*ap;
for(int j=0;j<=m;j++)
f[i][j]=max(f[i][j],f[i-1][j]);
if(i<=w) continue;
int l=1,r=0;
for(int j=0;j<=m;j++)
{
while(l<=r&&q[l]<j-as) l++;
while(l<=r&&f[i-w-1][q[r]]+q[r]*ap<=f[i-w-1][j]+j*ap) r--;
q[++r]=j;
if(l<=r) f[i][j]=max(f[i][j],f[i-w-1][q[l]]+q[l]*ap-j*ap);
}
l=1,r=0;
for(int j=m;j>=0;j--)
{
while(l<=r&&q[l]>j+bs) l++;
while(l<=r&&f[i-w-1][q[r]]+q[r]*bp<=f[i-w-1][j]+j*bp) r--;
q[++r]=j;
if(l<=r) f[i][j]=max(f[i][j],f[i-w-1][q[l]]+q[l]*bp-j*bp);
}
}
for(int i=0;i<=m;i++) ans=max(ans,f[n][i]);
cout<<ans<<endl;
}
最后一次更新于2021-09-28 02:20:25
0 条评论