【斜率优化】 POJ 1180 Batch Scheduling

通道

题意:一台机器要按照顺序完成n个任务,每个任务都有一个代价f和需要时间t。机器完成任务的方式是分批处理,对于每一批任务需要首先预处理s时间,同批任务中所有单个任务都是同时完成,代价为完成的时刻乘以各自的代价。求最小代价

思路:

分批考虑情况太多,可以先将问题转化。每个任务对对最后代价的贡献实际上等于它及它以后的f之和乘以它的时间t,即后面的任务都要为它等上t的时间,会多花f*t的代价。

找i的决策点的方法即min(dp[p]+(st[i]-st[p]+s)*sf[i]),st[i]为>=i的时间总和,sf[i]为大于等于i的代价总和,若两个决策点,j,k(j<k),存在j不比k更差,则意味着:

      dp[j]+(st[i]-st[j]+s)*sf[i]<=dp[k]+(st[i]-st[k]+s)*sf[i]   ==>  (dp[j]-dp[k])/(st[j]-st[k])<=sf[i]

      我们记用g(j,k)为用决策点j去取代k的代价函数,即考虑第i个点的时候如果发生了g(j,k)<=sf[i],那么用k就不如用j。

代码:

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int dp[12000],st[12000],sf[12000],L[12000];
int main()
{
    int n,s;
    while(scanf("%d%d",&n,&s)!=EOF)
    {
        for(int i=1;i<=n;i++)
            scanf("%d%d",st+i,sf+i);
        dp[n+1]=st[n+1]=sf[n+1]=0;
        for(int i=n;i>=1;i--)
            st[i]+=st[i+1],sf[i]+=sf[i+1];
        int a=0,b=0;
        L[a]=n+1;
        for(int i=n;i>=1;i--)
        {
            while(a<b&&dp[L[a+1]]-dp[L[a]]<=(st[L[a+1]]-st[L[a]])*sf[i])
                a++;
            dp[i]=dp[L[a]]+(st[i]-st[L[a]]+s)*sf[i];
            while(a<b&&(dp[i]-dp[L[b]])*(st[L[b]]-st[L[b-1]])<=(st[i]-st[L[b]])*(dp[L[b]]-dp[L[b-1]]))
                b--;
            L[++b]=i;
        }
        printf("%d\n",dp[1]);
    }
    return 0;
}
View Code

 

转载于:https://www.cnblogs.com/Rojo/p/4696188.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值