タイトル
ZJMがありますn個のジョブは、各ジョブには、独自のDDLを持ってZJMは、DDLの前に仕事をしていない場合は、教師がすべての通常ポイントをこの仕事が差し引かれます。
だから、ZJMはできるだけビット以下の点をバックルして宿題の順序を調整する方法を知りたいです。
入力
T検定の入力。最初の入力ラインは、テストケースの数で発見された、単一の整数Tです。
各テストケースは、正の整数Nを開始する(1 <= Nは<= 1000)、 ジョブの数を示します。
次に、2本のライン。最初の行は、DDL、バックル点を表すN個の整数を含む次の行を表すN個の整数を含みます。
出力
各テストケースについて、あなたは最小合計スコアの出力、各試験ラインを減らす必要があります。
サンプル入力
3
3
3 3 3
10 5 1
3
1 3 1
6 2 3
7
1 4 6 4 2 4 3
3 2 1 7 6 5 4
サンプル出力
0
3
5
思考
貪欲なアルゴリズムを使用します。
この方法は、タスクがポイントに応じて降順にソートされることを考えるのは簡単ですが、タスクに時間を手配するために、トラバーサルが続きます。見つかった空き時間は、この日に予定されている場合は、最初のタスクのために私は、タスクから前方に横断するDDL。明らかに、この複雑さはO(N ^ 2)、少ないデータ量が1000を処理することができるよりもあります。
だから、あまり複雑方法はありますか?
バックからスケジュールタスクごとに一日に毎日列挙する。列挙X、Xの最初の日はポイントは、最初のタスクが予定日Xソートされ降順に従ってすべてのDDLタスクよりも大きいです。大ルートスタック- O(LOGN)のデータ構造の複雑さを選択する仕分け作業、。したがって、この方法は、O(nlogn)の複雑さです。
コード
#include <cstdio>
#include <algorithm>
using namespace std;
struct work{
int ddl,score;
bool operator<(work w)const{
if(ddl!=w.ddl)
return ddl>w.ddl;
else
return score>w.score;
}
}w[2000];
bool cmp(work a,work b){
if(a.score!=b.score)
return a.score>b.score;
else
return a.ddl>b.ddl;
}
int main() {
int t,n,maxDDL,total,sum;
scanf("%d",&t);
for(int k=0;k<t;k++){
maxDDL=0;total=0;sum=0;
scanf("%d",&n);
for(int i=0;i<n;i++){
scanf("%d",&w[i].ddl);
if(w[i].ddl>maxDDL)
maxDDL=w[i].ddl;
}
for(int i=0;i<n;i++){
scanf("%d",&w[i].score);
total+=w[i].score;
}
sort(w,w+n);
int j=0;
for(int i=maxDDL;i>0;i--){
while(j<n&&w[j].ddl>=i){
j++;
}
sort(w,w+j,cmp);
sum+=w[0].score;
w[0].score=0;
}
printf("%d\n",total-sum);
}
return 0;
}