当前位置: 代码迷 >> 综合 >> poj 1180 Batch Scheduling dp斜率优化
  详细解决方案

poj 1180 Batch Scheduling dp斜率优化

热度:78   发布时间:2024-01-19 05:23:08.0
题意:
       设dp[i]=min dp[j]+(S+sumT[i]-sumT[j])*F[i]  1<=i<=N,i<j<=N+1,sumT[i]=T[i]+T[i+1]+...+T[N],sumF[i]=F[i]+F[i+1]+...+F[N],求dp[1]。
分析:

       dp[i]=min (S+sumT[i])*sumF[i]+dp[j]-sumT[j]*F[i],由于F[i]随i减小单增,sumT[j]随i减小单增,按照i从N到1倒推dp[i]满足单调队列优化的条件dp[i]=S(i)+min{fj(i)|i<j<=N+1},其中S(i)是i的任意函数,fj是由j确定直线,使用单调队列优化到O(n)。

代码:

//poj 1180
//sep9
#include <iostream>
#include <deque>
using namespace std;
const int MAXN=10024;
int N,S,T[MAXN],F[MAXN],sumT[MAXN],sumF[MAXN],dp[MAXN];struct Line{int k,b;Line(int k,int b):k(k),b(b){}		
};int f(int x,Line l)
{return (S+sumT[x])*sumF[x]+l.b+l.k*sumF[x];
}bool check(Line l1,Line l2,Line l3)
{return (l2.k-l1.k)*(l3.b-l2.b)>=(l2.b-l1.b)*(l3.k-l2.k);
}int main()
{scanf("%d%d",&N,&S);for(int i=1;i<=N;++i)scanf("%d%d",&T[i],&F[i]);sumT[N+1]=sumF[N+1]=0;for(int i=N;i>=1;--i){sumT[i]=sumT[i+1]+T[i];sumF[i]=sumF[i+1]+F[i];}deque<Line> lines;lines.push_back(Line(0,0));for(int i=N;i>=1;--i){while(lines.size()>1&&f(i,lines[0])>=f(i,lines[1])) lines.pop_front();dp[i]=f(i,lines[0]);Line l(-sumT[i],dp[i]);while(lines.size()>1&&check(lines[lines.size()-2],lines[lines.size()-1],l)) lines.pop_back();lines.push_back(l);}printf("%d\n",dp[1]);	return 0;	
}


  相关解决方案