p1848 [USACO12OPEN]书架Bookshelf
分析
单调队列优化dp即可
正确性显然,详见代码
代码
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N = 1e6;
int w[N+10],h[N+10],dp[N+10],q[N+10],le,ri,n,m;
signed main(){
int i,j,k,wh=1,sum=0;memset(dp,0x7f,sizeof(dp));dp[0]=0;q[++ri]=0;le++;
scanf("%lld%lld",&n,&m);for(i=1;i<=n;i++)scanf("%lld%lld",&h[i],&w[i]);
for(i=1;i<=n;i++){
sum+=w[i];while(sum>m)sum-=w[wh],wh++;while(le<=ri&&q[le]<wh)le++;while(le<=ri&&h[q[ri]]<=h[i])ri--;
q[++ri]=i;for(j=le;j<ri;j++)dp[i]=min(dp[i],dp[q[j]]+h[q[j+1]]);dp[i]=min(dp[i],dp[wh-1]+h[q[le]]);
}
printf("%lld\n",dp[n]);return 0;
}