今日の「計算理論とアルゴリズムの設計」の最終試験の3つのプログラミングの質問を更新してください。テストケースのない質問は、本当に受け入れられません。私は試験中に自分の考えを共有し、最後に私が書いたセルフテストのユースケースを配りました。参考までに、エラーを指摘してください〜
02
グレード 15 開始時間 2020年6月24日水曜日15:10 ディスカウント 0.8 割引時間 2020年6月24日水曜日18:30 遅延提出が可能 番号 閉店時間 2020年6月24日水曜日18:30 タイトル説明:
現在、マシンはn個のタスクを処理する必要があり、各タスクは時間単位で完了することができます。各タスクには、期限(d1、d2 ,,…、dn)と、期限内に完了しないペナルティ係数(w1、w2 ,,…、wn)があります。すべてのタスク配置でペナルティファクタの最小合計を見つけます。たとえば、3つのタスクがある場合、期限は(2,2,2)であり、ペナルティ係数は(6,7,8)です。123、132、213、231、312、および321のペナルティファクタは、それぞれ8、7、8、6、7、および6です。6は、すべてのタスク配置におけるペナルティファクターの合計の最小値であることがわかります。
入力フォーマット:
3行あり、1行目は整数n(0 <n <= 10000)、2行目はn正の整数d1、d2 、、 ...、dn(intであることが保証されています)、3行目はn正整数ですw1、w2 ,,…、wn(intであることが保証されています)。
出力フォーマット:
1行あたり1つの数値は、最小ペナルティファクターの合計です。
テスト入力 期待される出力 制限時間 メモリ制限 追加プロセス テストケース1
- 3↵
- 2 22↵
- 6 78↵
- 6↵
1秒 64M 0
この質問は明らかに貪欲です。一般的な考え方は次のとおりです。より厳しい罰則でタスクに優先順位を付け、各タスクがdllに最も近い時間に完了するように手配します。この質問は貪欲な選択の性質を満たしていることが証明できるので、貪欲な戦略も正しいです。
1.データの前処理
まず、タスクは、タスクのDDLとペナルティウェイトを含む構造で表されます。次に、タスクのthing []配列を作成し、重みをキーとして降順に配列を並べ替えます。
struct node {
int deadLine; //ddl
int weight; //惩罚
} thing[MAXN];
bool cmp(struct node x, struct node y) {
if (x.weight == y.weight) //当惩罚一样时
return x.deadLine < y.deadLine; //优先ddl在前面的
else
return x.weight > y.weight; //优先惩罚更重的
}
さまざまな配列の入力処理と初期化は、Init()関数で実装されます。期間のスケジューリングを容易にするために、タイムスロットを定義します。配列done []で表されます。done [i] = trueの場合、i番目の単位期間がアイドル状態であることを意味します。したがって、doneをすべてtrueに初期化し、競合を回避するために時間を割り当てるたびにfalseを割り当てる必要があります。
void Init() {
scanf("%d", &n);
for (int i = 1; i <= n; i++)
scanf("%d", &thing[i].deadLine);
for (int i = 1; i <= n; i++)
scanf("%d", &thing[i].weight);
for(int i = 0;i <= n; i++)
done[i] = true;
}
2.貪欲な実現
並べ替えられた順序に従って(つまり、より重い罰則でタスクに優先順位を付ける)、各タスクを順番に検討し、dllに最も近い時間に完了するように調整します。見つからない場合は完了できません。
/* 为任务t寻找合适的时间
* 找不到则返回false */
bool Done(struct node t) {
//找到最接近ddl的空闲时间段
for(int i = t.deadLine; i >= 1; i--)
if(done[i]) {
done[i] = false;
return true;
}
//找不到则返回假
return false;
}
int Calc() {
sort(thing + 1, thing + n + 1, cmp); //对任务以惩罚为关键字排序
int ans= 0;
for(int i = 1; i <= n; i++) {
if(!Done(thing[i])) //对于找不到合适时间的任务
ans += thing[i].weight; //加入惩罚
}
return ans;
}
完全なコードとテストケースを以下に添付します。
#include <cstdio>
#include <algorithm>
#define MAXN 10050
using namespace std;
int n;
bool done[MAXN]; //第i个时间段是否有空
struct node {
int deadLine; //ddl
int weight; //惩罚
} thing[MAXN];
bool cmp(struct node x, struct node y) {
if (x.weight == y.weight) //当惩罚一样时
return x.deadLine < y.deadLine; //优先ddl在前面的
else
return x.weight > y.weight; //优先惩罚更重的
}
void Init() {
scanf("%d", &n);
for (int i = 1; i <= n; i++)
scanf("%d", &thing[i].deadLine);
for (int i = 1; i <= n; i++)
scanf("%d", &thing[i].weight);
for(int i = 0;i <= n; i++)
done[i] = true;
}
/* 为任务t寻找合适的时间
* 找不到则返回false */
bool Done(struct node t) {
//找到最接近ddl的空闲时间段
for(int i = t.deadLine; i >= 1; i--)
if(done[i]) {
done[i] = false;
return true;
}
//找不到则返回假
return false;
}
int Calc() {
sort(thing + 1, thing + n + 1, cmp); //对任务以惩罚为关键字排序
int ans= 0;
for(int i = 1; i <= n; i++) {
if(!Done(thing[i])) //对于找不到合适时间的任务
ans += thing[i].weight; //加入惩罚
}
return ans;
}
int main() {
Init();
printf("%d\n", Calc());
}
テストケース:
4
1 1 3 4
7 8 9 10
出力:7
4
2 2 2 1
16 7 8 2
出力:9
5
5 5 2 2 3
12 3 1 2 9
出力:0
6
3 3 3 4 4 4
7 8 9 12 1 3
出力:4
8
1 1 1 2 2 2 3 3
1 2 3 1 3 3 5 4
出力:10
3
2 2 26 7 8
出力:6
4
1 1 2 3
1 2 7 9
出力:1
6
1 3 4 4 6 1
21 2 20 9 25 15
出力:15
6
6 1 4 1 4 3
0 4 5 10 16 23
出力:4
7
4 2 4 3 1 4 6
70 60 50 40 30 20 10
出力:50
終わり
個人のパブリックアカウント「 チキンウィングプログラミング」に注意を払うことを歓迎します。ここには、真面目で行儀のよいコードファーマーがいます。
----最も行儀の良いブロガーであり、最も堅実なプログラマーになる----
それぞれの記事を注意深く書くことを目指し、通常はメモをプッシュ更新にまとめます〜