【题解/模板】P1248 加工生产调度(贪心)
分析:
- \(A\)流水线的时间是确定的,所以现在就是要让\(b\)的时间尽量短
- \(tB > tA\),除非所有东西都不需要\(b\)。(t指结束时间)
性质:
- 对于一个\((a,b)\)若\(a< b\),让他先做更优秀。
- 同\(a<b\)的二元组,\(a\)小的更有优势。可以相对短一点点\(A,B\)时间差
- 对于一个\((a,b)\)若\(a\ge b\),不如在后面做这些东西,不然会让\(b\)空转。
- 同\(a \ge b\)的二元组,\(b\)大的更有优势。理由一样。
然后排序+模拟就写完了,其实这道题很难,不过分析一波性质后就很简单。我很惭愧地将若非看了题解不然想不到啊....
//@winlere
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std; typedef long long ll;
inline int qr(){
register int ret=0,f=0;
register char c=getchar();
while(c<48||c>57)f|=c==45,c=getchar();
while(c>=48&&c<=57) ret=ret*10+c-48,c=getchar();
return f?-ret:ret;
}
const int maxn=1e3+5;
vector<pair< pair<int,int> , int > > v1,v2,ve;
pair<int,int> data[maxn];
int n;
int main(){
n=qr();
for(int t=1;t<=n;++t) data[t].first=qr();
for(int t=1;t<=n;++t) data[t].second=qr();
for(int t=1,t1,t2;t<=n;++t){
t1=data[t].first;
t2=data[t].second;
if(t1<t2) v1.push_back({{t1,t2},t});
else v2.push_back({{-t2,t1},t});
}
sort(v1.begin(),v1.end());
sort(v2.begin(),v2.end());
for(auto&t:v2) swap(t.first.first,t.first.second),t.first.second=-t.first.second;
for(auto t:v1) ve.push_back(t);
for(auto t:v2) ve.push_back(t);
ll t1=0,t2=0;
for(auto t:ve){
t1=t1+t.first.first;
t2=max(t1,t2)+t.first.second;
//printf("{{%d,%d},%d}=%lld,%lld ",t.first.first,t.first.second,t.second,t1,t2);
}
printf("%lld\n",t2);
for(auto t:ve) printf("%d ",t.second);
putchar('\n');
return 0;
}