機 器上有n個需要處理的任務,它們構成了乙個序列。這些任務被標號為1到n,因此序列的排列為1,2,3...n。這n個任務被分成若干批,每批包含相鄰的 若干任務。從時刻0開始,這些任務被分批加工,第i個任務單獨完成所需的時間是ti。在每批任務開始前,機器需要啟動時間s,而完成這批任務所需的時間是 各個任務需要時間的總和。注意,同一批任務將在同一時刻完成。每個任務的費用是它的完成時刻乘以乙個費用係數fi。請確定乙個分組方案,使得總費用最小。
第一行兩個整數,n,s。
接下來n行每行兩個整數,ti,fi。
乙個整數,為所求的答案。
5 11 3
3 24 3
2 31 4
153這個題一開始想著去處理乙個人等了多長時間
然後就會發現等的時間是和前面分了多少批有關的,這樣的話我們需要用二維狀態表示到這個點,前面分了多少批
這樣暴力n^3會很萎
這時候我們會回想起乙個叫做修車的題目,他對於每個點的處理相當於是這個點讓後面的人多等了多久
那我們可以通過同樣的方式思考,每分了一批其實就是讓後面的所有人多等了乙個s的時間,其餘的並不影響
那麼我們可以推出一維的狀態
f[i]=min(f[j]+s*(f[n]-f[j])+t[i]*(f[i]-f[j]));
對於前百分之60的資料,t為正數,滿足決策單調性,可以二分棧,但我懶得打了,就在codevs上ac了乙個弱化版的n^2;
斜率優化+cdq在下面
// made by qt666#include#include#include#include#include#include#include#include#include#include#define lson num<<1
#define rson num<<1|1
#define int long long
using namespace std;
typedef long long ll;
const int n=100050;
int gi()
while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();
return x*flag;
}int f[n],t[n],f[n],s,n;
int cal(int j,int i)
main()
while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();
return x*flag;
}struct data g[n],q[n],p[n];
bool cmp(data a,data b)
for(int i=l;i<=r;i++) g[i]=p[i];
solve(l,mid);
for(int i=l;i<=mid;i++)
//sort(g+mid+1,g+r+1,cmp);
for(int i=mid+1;i<=r;i++)
solve(mid+1,r);l1=l,l2=mid+1;
for(int i=l;i<=r;i++)
for(int i=l;i<=r;i++) g[i]=p[i];
}main()
for(int i=1;i<=n;i++) f[i]=s*f[n]+t[i]*f[i],g[i].b=f[i]-s*f[i];
sort(g+1,g+n+1,cmp);solve(1,n);
printf("%lld",f[n]);
}
Bzoj 2726 SDOI 任務安排
memory limit 131072kb 64bit io format lld llu description 機器上有n個需要處理的任務,它們構成了乙個序列。這些任務被標號為1到n,因此序列的排列為1,2,3.n。這n個任務被分成若干批,每批包含相鄰的若干任務。從時刻0開始,這些任務被分批加工...
bzoj 2726 SDOI2012 任務安排
機器上有n個需要處理的任務,它們構成了乙個序列。這些任務被標號為1到n,因此序列的排列為1,2,3 n。這n個任務被分成若干批,每批包含相鄰的若干任務。從時刻0開始,這些任務被分批加工,第i個任務單獨完成所需的時間是ti 在每批任務開始前,機器需要啟動時間s,而完成這批任務所需的時間是各個任務需要時...
BZOJ 2726 SDOI2012 任務安排
bzoj 2726 sdoi2012 任務安排 斜率優化 二分 機器上有n個需要處理的任務,它們構成了乙個序列。這些任務被標號為1到n,因此序列的排列為1,2,3.n。這n個任務被分成若干批,每批包含相鄰的若干任務。從時刻0開始,這些任務被分批加工,第i個任務單獨完成所需的時間是ti。在每批任務開始...