題目
http://poj.org/problem?id=1180
解題思路
的
每個待求解的狀態都對應着一條直線的截距,直線的斜率是,截距未知。當截距最小化,也取到最小值。
有三個決策點
有可能成爲最優決策,當且僅當
用單調隊列維護
代碼
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
int n,s,t,c,sumt[10001],sumc[10001],f[10001],q[10001];
int main(){
scanf("%d%d",&n,&s);
for(int i=1;i<=n;i++) scanf("%d%d",&t,&c),sumt[i]=sumt[i-1]+t,sumc[i]=sumc[i-1]+c;
memset(f,0x3f,sizeof(f));
int l=1,r=1; q[1]=0; f[0]=0;
for(int i=1;i<=n;i++){
while(l<r&&(f[q[l+1]]-f[q[l]])<=(s+sumt[i])*(sumc[q[l+1]]-sumc[q[l]])) l++;
f[i]=f[q[l]]-(s+sumt[i])*sumc[q[l]]+sumt[i]*sumc[i]+s*sumc[n];
while(l<r&&(f[q[r]]-f[q[r-1]])*(sumc[i]-sumc[q[r]])>=(f[i]-f[q[r]])*(sumc[q[r]]-sumc[q[r-1]])) r--;
q[++r]=i;
}
printf("%d",f[n]);
}