CF::Gym 100113K - The Merry Student Life During the Term. . .

CF :: Gym portal page topic

There \ (n-\) set of tasks, each \ (m_i \) th, \ (I \) of Group \ (J \) task numbered \ (\ sum \ limits_ {k = 1} ^ {i M_k + J} -1 \) . The first \ (i \) tasks required \ (a_i \) units of time to complete. Just start time \ (0 \) , each completed a task \ (i \) current time increases \ (a_i \) . If the first \ (i \) task completion time for the \ (t \) , is subject to penalties as \ (b_it \) . Do a task from start to finish is not allowed to do other tasks, do a set of tasks from start to finish does not allow other groups to do the task. Seeking an optimal order to complete the task, so that the total minimum penalty being. Penalties and minimum total output sequence. If multiple solutions, any one output.

For a task group in any sequence, it is clear that in this sequential order within each group the minimum total penalty is unchanged. Thus considering first order within each group to obtain the optimum, then the optimum sequence of tasks seeking groups.

Like this seek the optimal order of questions, often have a routine. For each \ (I \) , consider the sequence of any one exchange \ (the ord \) any adjacent pair \ ((ord_x, ord_ +. 1 {X}) \) , it becomes \ ((ord_ { . 1} + X, ord_x) \) , will better. Obviously, \ ({ord_. 1 \ SIM. 1-X}, {X + 2 ord_ \ SIM m_i} \) of the total contribution of punishment and will not (ord_x, ord_ {x + 1 } \) \ exchange vary, we just need to care about \ (ord_x, ord_ {x + 1} \) contribution to the total penalties and. Set \ (SUM = \ SUM \ limits_ {J =. 1} ^ {X-. 1} A_ {ord_j} \) , then \ (ord_x, ord_ {x + 1} \) their contribution and for the next order of the total penalties \ (b_ {ord_x} (sum + a_ {ord_x}) + b_ {ord_ {x + 1}} (sum + a_ {ord_x} + a_ {ord_ {x + 1}}) = b_ {ord_x} sum + b_ {ord_x} a_ {ord_x} + b_ {ord_ {x + 1}} sum + b_ {ord_ {x + 1}} a_ {ord_x} + b_ {ord_ {x + 1}} a_ {ord_ {x + 1} } = (b_ {ord_x} + b_ {ord_ {x + 1}}) sum + a_ {ord_x} b_ {ord_x} + a_ {ord_ {x + 1}} b_ {ord_ {x + 1}} + a_ { B_ {} {ord_ ord_x X +. 1}} \) ; similarly, can be obtained\ (ord_ {x + 1} , ord_x \) contribution to the total penalty in order and to \ ((b_ {ord_x} + b_ {ord_ {x + 1}}) sum + a_ {ord_x} b_ {ord_x} + {{X + ord_ A_. 1 ord_ {} {} B_. 1}} + X + X + A_ {ord_. 1 {{}} B_ ord_x} \) . When \ ((b_ {ord_x} + b_ {ord_ {x + 1}}) sum + a_ {ord_x} b_ {ord_x} + a_ {ord_ {x + 1}} b_ {ord_ {x + 1}} + a_ {ord_x} b_ {ord_ {x + 1}}> (b_ {ord_x} + b_ {ord_ {x + 1}}) sum + a_ {ord_x} b_ {ord_x} + a_ {ord_ {x + 1}} b_ {ord_ {X +. 1}} + A_ {ord_ {X +. 1}} B_ {ord_x} \) , i.e. \ (a_ {ord_x} b_ { ord_ {x + 1}}> a_ {ord_ {x + 1} } b_ {ord_x} \) , the exchange will be apparent \ (ord_x, ord_ {x + 1} \) to give better strategy. We will be in such a sequence can make the policy better exchange of neighboring called "adjacent to reverse."

Clearly, there is a certain order to adjacent reverse is not optimal. We forget that order is not adjacent to the reverse must be optimal. Thus we define a comparator \ (CMP (X, Y) = [a_xb_y <a_yb_x] \) , according to which all the elements within the set of ordered, this order must be obtained optimal. \ ([a_xb_y <a_yb_x] \ ) can be deformed \ (\ left [\ dfrac {a_x} {B_X} <\ dfrac {a_y} {b_y} \ right] \) , Thus, the comparator \ (CMP \ ) legitimacy is clear. In this case, "adjacent reverse order is not necessarily optimal for the" This conclusion is also clear that the accuracy: After drained sequence, if \ (\ dfrac {a_x} { b_x} = \ dfrac {a_y} {b_y } \) , then \ (X \) and \ (Y \) certain adjacent, any \ (2 \) ordered in the sequence will be able to reach each other by rearranging each segment are equal, then easy to prove that all sequenced equal to the total punishment order, is proved.

Obtaining the optimal order within each group, the order now to find the optimal task group. The above is the default start time for each group to \ (0 \) , but not necessarily now. Set \ (sum \ _a_i = \ sum \ limits_ {j = \ sum \ limits_ {k = 1} ^ {i-1} m_k + 1} ^ {\ sum \ limits_ {k = 1} ^ im_k} a_j, sum \ _b_i = \ SUM \ limits_ = {J \ SUM \ limits_. 1} ^ {K = {I}. 1-M_k +. 1} ^ {\ SUM \ limits_. 1} = {K} b_j im_k ^ \) . For a sequence \ (the ord \) , the first \ (ord_i \) start time of the group is clearly \ (\ SUM \ limits_ {J =. 1} ^ {I-. 1} SUM \ _a_, {ord_j} \) , which than begins time \ (0 \) contribution to the overall increase in penalty \ (SUM \ _b_ ord_i} {\ SUM \ limits_. 1} = {J ^ {I}. 1-SUM \ _a_, ord_j} {\) . So, we can set each task as a big task, according to a method similar to the above definition of a comparator \ (cmp '(x, y ) = \ left [sum \ _a_xsum \ _b_y <sum \ _a_ysum \ _b_x \ right] \) and follow it all the tasks set sorting, you can get the optimal order.

Here is the AC codes:

#include<bits/stdc++.h>
using namespace std;
#define int long long
#define pb push_back
const int N=500,M_I=100;
int n;//任务组数 
int m[N+1];//每组任务个数 
int a[N+1][M_I+1]/*所需时间*/,b[N+1][M_I+1]/*处罚系数*/;
int sum_a[N+1]/*该组内所有任务所需时间之和*/,sum_b[N+1]/*该组内所有任务处罚系数之和*/;
int now;//当前正在处理的任务组 
bool cmp(int x,int y){return a[now][x]*b[now][y]<a[now][y]*b[now][x];}//给组内任务排序的比较器 
bool cmp0(int x,int y){return sum_a[x]*sum_b[y]<sum_a[y]*sum_b[x];}//给任务组排序的比较器 
vector<int> ord[N+1]; 
signed main(){
//  freopen("student.in","r",stdin);freopen("student.out","w",stdout);
    cin>>n;
    for(int i=1;i<=n;i++)cin>>m[i];
    for(int i=1;i<=n;i++)for(int j=1;j<=m[i];j++)cin>>a[i][j];
    for(int i=1;i<=n;i++)for(int j=1;j<=m[i];j++)cin>>b[i][j];
    int ans=0;
    int cnt=0;
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m[i];j++)sum_a[i]+=a[i][j],sum_b[i]+=b[i][j];//计算sum_a,sum_b 
        vector<int> v(m[i]); 
        for(int j=1;j<=m[i];j++)v[j-1]=j;
        now=i;
        sort(v.begin(),v.end(),cmp);//排序 
        int tim=0;
        for(int j=0;j<m[i];j++)ans+=b[i][v[j]]*(tim+=a[i][v[j]]);//贡献答案 
        for(int j=0;j<m[i];j++)ord[i].pb(cnt+v[j]);//记录最优顺序 
        cnt+=m[i];
    }
    vector<int> v(n);
    for(int j=1;j<=n;j++)v[j-1]=j;
    sort(v.begin(),v.end(),cmp0);//排序 
    int tim=0;
    for(int i=0;i<n;i++)ans+=tim*sum_b[v[i]],tim+=sum_a[v[i]];//贡献答案 
    cout<<ans<<"\n";//输出答案 
    for(int i=0;i<n;i++)for(int j=0;j<m[v[i]];j++)cout<<ord[v[i]][j]<<" ";//输出顺序 
    return 0;
}

Guess you like

Origin www.cnblogs.com/ycx-akioi/p/CF-Gym-100113K.html