单调队列优化。
好像有点烦。。。调了许久。
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #define maxn 7050 using namespace std; long long n,m,v[maxn],w[maxn],c[maxn],up[maxn],q[maxn],l,r,ret1,ret2,val[maxn],dp[maxn]; void get_up(long long x) { for (long long i=0;i<=m%v[x];i++) up[i]=(m/v[x])*v[x]+i; for (long long i=m%v[x]+1;i<=v[x]-1;i++) up[i]=(m/v[x]-1)*v[x]+i; } void insert(long long x,long long y,long long z) { while ((l<=r) && (val[r]<=dp[x]-y*w[z])) r--; q[++r]=x;val[r]=dp[x]-y*w[z]; } int main() { scanf("%lld%lld",&n,&m); for (long long i=1;i<=n;i++) scanf("%lld%lld%lld",&v[i],&w[i],&c[i]); for (long long i=1;i<=n;i++) { get_up(i); for (long long j=0;j<v[i];j++) { l=1;r=0;long long now=up[j],lim=up[j];ret1=ret2=up[j]/v[i]; while (now>=0) { while ((l<=r) && (q[l]>now)) l++; while ((lim>=now-c[i]*v[i]) && (lim>=0)) { insert(lim,ret2,i); lim-=v[i];ret2--; } dp[now]=val[l]+ret1*w[i];ret1--;now-=v[i]; } } } printf("%lld ",dp[m]); return 0; }