Time Limit: 1000MS | Memory Limit: 10000K | |
Total Submissions: 4347 | Accepted: 1992 |
Description
A setup time S is needed to set up the machine for each batch. For each job i, we know its cost factor Fi and the time Ti required to process it. If a batch contains the jobs x, x+1,... , x+k, and starts at time t, then the output time of every job in that batch is t + S + (T x + T x+1 + ... + T x+k ). Note that the machine outputs the results of all jobs in a batch at the same time. If the output time of job i is Oi, its cost is Oi * Fi. For example, assume that there are 5 jobs, the setup time S = 1, (T1, T2, T3, T4, T5) = (1, 3, 4, 2, 1), and (F1, F2, F3, F4, F5) = (3, 2, 3, 3, 4). If the jobs are partitioned into three batches {1, 2}, {3}, {4, 5}, then the output times (O1, O2, O3, O4, O5) = (5, 5, 10, 14, 14) and the costs of the jobs are (15, 10, 30, 42, 56), respectively. The total cost for a partitioning is the sum of the costs of all jobs. The total cost for the example partitioning above is 153.
You are to write a program which, given the batch setup time and a sequence of jobs with their processing times and cost factors, computes the minimum possible total cost.
Input
Output
Sample Input
5 1 1 3 3 2 4 3 2 3 1 4
Sample Output
153
Source
dp[i]=min(dp[j]+(sunT[i]-sumT[j]+s)*sumF[i]) (1<=i<=n+1;i<j<=n+1)
We consider that when calculating dp[i], for i < j < k, if the condition that decision k is guaranteed to be greater than decision j is: dp[j] + (S + sumT[i] - sumT[j]) * sumF[i] < dp[k] + (S + sumT[i] -sumT[k]) * sumF[i]
By shifting items, it can be simplified to: (dp[j] - dp[k]) / (sumT[j] - sumT[k]) < sumF[i]
It can be seen that when we calculate dp[i], if (dp[j] - dp[k]) / (sumT[j] - sumT[k]) >=sumF[i], we can discard j (decision K is better than decision j);
Therefore, we can use a monotonic queue. When the element i needs to be paired, (i<j<k), how do we maintain it? Let’s set the function Q(j,k)=(dp[j] - dp[k]) / (sumT[j] - sumT[k]);
Because i needs to be paired, what we need to discuss is whether we need to keep the decision j, (we will discuss the conditions for J to be discarded below);
If j needs to be discarded, that is, for decision i, j, i is better than j; for decision j, k, k is better than j; so we have Q(i,j)<sumF[i],sumF[i]<=Q (j,k); That is, Qi,j)<Q(j,k);
To sum up: you can consider maintaining a queue with a slope to optimize the entire DP process:
(1) Assuming that i (the element to be enqueued soon) < j < k is the element at the end of the queue, then we have to consider whether Q(i,j) is greater than Q(j,k), if Q(i,j) ) < Q(j,k), then it is certain that j will not be a decision point, and j can be removed from the queue and pushed forward in turn until a queue with less than 2 elements is found or Q(i,j)> = Q(j,k) to stop.
(2) Assuming k>j (k is the head element) is the element that is the head of the queue in turn, if g(j,k) < sumF[i], then decision point j is definitely better than decision point k for i , and since sumF[i] increases as i decreases,
So when Q(j,k) < sumF[i], there must be Q(j,k) < sumF[i-1], so the current decision point k is not only when considering dp[i] The best decision point, and it must not be the best decision point in the following DP, so we can delete k from the head of the queue, and so on in turn, until the queue element is less than 2 or Q(j,k )>= sumF[i].
Code:
1 #include<sstream> 2 #include<iomanip> 3 #include"cstdio" 4 #include"map" 5 #include"set" 6 #include"cmath" 7 #include"queue" 8 #include"vector" 9 #include"string" 10 #include"cstring" 11 #include"time.h" 12 #include"iostream" 13 #include"stdlib.h" 14 #include"algorithm" 15 #define db double 16 #define ll long long 17 #define vec vectr<ll> 18 #define mt vectr<vec> 19 #define ci(x) scanf("%d",&x) 20 #define cd(x) scanf("%lf",&x) 21 #define cl(x) scanf("%lld",&x) 22 #define pi(x) printf("%d\n",x) 23 #define pd(x) printf("%f\n",x) 24 #define pl(x) printf("%lld\n",x) 25 //#define rep(i, x, y) for(int i=x;i<=y;i++) 26 #define rep(i, n) for(int i=0;i<n;i++) 27 const int N = 1e4+ 5; 28 const int mod = 1e9 + 7; 29 const int MOD = mod - 1; 30 const int inf = 0x3f3f3f3f; 31 const db PI = acos(-1.0); 32 const db eps = 1e-10; 33 using namespace std; 34 ll dp[N]; 35 int st[N],sf[N],deq[N]; 36 int t[N],f[N]; 37 int n,s; 38 db cal(int x,int y){ 39 return db(dp[x]-dp[y])/db(st[x]-st[y]); 40 } 41 int main() 42 { 43 ci(n),ci(s); 44 for(int i=1;i<=n;i++) ci(t[i]),ci(f[i]); 45 for(int i=n;i;i--) st[i]=st[i+1]+t[i],sf[i]=sf[i+1]+f[i]; 46 int l=1,r=0; 47 dp[n]=(s+st[n])*sf[n]; 48 deq[++r]=n; 49 for(int i=n-1;i;i--) 50 { 51 while(r-l>=1 && cal(deq[l],deq[l+1])<sf[i]) l++; 52 int tt=s+st[i]; 53 tt*=sf[i]; 54 dp[i]=tt; 55 int j=deq[l]; 56 tt=s+st[i]-st[j]; 57 tt*=sf[i]; 58 dp[i]=min(dp[i],dp[j]+tt); 59 while(r-l>=1 && cal(deq[r-1],deq[r])>cal(deq[r],i)) r--; 60 deq[++r]=i; 61 } 62 pl(dp[1]); 63 return 0; 64 }