kkksc03試験前に一時的に仏の足を握る
トピックの背景
Kkksc03の大学生活は退廃的で、まったく勉強していません。しかし、彼は期末試験に近づいたので、彼は主題を離れないように仏の足を受け入れ始めなければなりませんでした。
タイトルの説明
この最終試験では、kkksc03が\(4 \)科目を履修する必要があります。したがって、問題セットのブラッシングを開始するには、各サブジェクトに\(s_1、s_2、s_3、s_4 \)の問題がある問題セットがあり、各問題の完了には時間がかかります。 ldots、A_ {s_1} \)、\(B_1、B_2、\ ldots、B_ {s_2} \)、\(C_1、C_2、\ ldots、C_ {s_3} \)、\(D_1、D_2、\ ldots、 D_ {s_4} \))。
kkksc03には能力があり、彼の左脳と右脳は同時に\(2 \)の異なるトピックを計算できますが、同じ主題でのみです。したがって、kkksc03は1つずつ確認する必要があります。
kkksc03はまだLuoguのバグに対処することを切望しているため、できるだけ早く作業を終了したいと考えているため、レビューを完了する最短の時間を知りたいと考えています。
入出力フォーマット
入力フォーマット
この質問には、\(5 \)行のデータが含まれています:行\(1 \)は、4つの正の整数\(s_1、s_2、s_3、s_4 \)です。
行\(2 \)は、\(A_1、A_2、\ ldots、A_ {s_1} \)内の\(s_1 \)の総数であり、最初の主題問題セットの各質問が費やした時間を表します。
行\(3 \)は、\(B_1、B_2、\ ldots、B_ {s_2} \)内の\(s_2 \)の総数です。
行\(4 \)は、\(C_1、C_2、\ ldots、C_ {s_3} \)内の\(s_3 \)の総数です。
行\(5 \)は\(D_1、D_2、\ ldots、D_ {s_4} \)、合計\(s_4 \)であり、意味は上記と同じです。
出力フォーマット
ラインが出力されます。これは、レビューの最短時間です。
入力と出力の例
入力サンプル#1
1 2 1 3
5
4 3
6
2 4 3
出力例#1
20
解説
\(1 \ leq s_1、s_2、s_3、s_4 \ leq 20 \)。
\(1 \ leq A_1、A_2、\ ldots、A_ {s_1}、B_1、B_2、\ ldots、B_ {s_2}、C_1、C_2、\ ldots、C_ {s_3}、D_1、D_2、\ ldots、D_ { s_4} \ leq60 \)。
分析
まず、この質問では、kkkは4つの科目をとる必要があります。明らかに、kkkの左脳計算と右脳計算は同じ主題でなければならないため、これらの4つの主題は互いに関連していません。したがって、全体の最適解は実際には4人の主題の最適解の合計です。次に、1つの主題を分析します。
明らかに、特定の主題の各質問の時間の合計がsum
最良の場合sum / 2
、それは左と右の脳が分かれていることを意味します。しかし、ほとんどの場合これを行うことはできず、左右の脳の時間差をできるだけ小さくすることができます。
考えを変えて、脳の半分にできる限り近くでエクササイズを割り当てることができます。sum / 2
そのとき、この時点で他の脳が必要とする時間は、この対象にとって最適なソリューションです。
言い換えれば、エクササイズはできるだけいっぱいにして、sum / 2
超えsum / 2
ないようにしてください。各エクササイズは選択のみ可能で、選択はできません。
それはどうですか、それを考え出してください、それは適切な01
バックパックです。01
バックパックのアイデアに従ってください。
最後に、4つの主題の最適解を追加することが答えです。
話は安いです、あなたにコードを見せてください。
コード
/*
* @Author: crab-in-the-northeast
* @Date: 2020-04-12 20:54:32
* @Last Modified by: crab-in-the-northeast
* @Last Modified time: 2020-04-12 21:53:26
*/
#include <iostream>
#include <cstdio>
#include <cstring>
inline int max(int a, int b) {
return a > b ? a : b;
}
int main() {
int s[5], ans = 0;
for(int i = 1; i <= 4; i++) std :: cin >> s[i];
for(int i = 1; i <= 4; i++) {
int sum = 0, a[25], dp[1205] = {0};
for(int j = 1; j <= s[i]; j++) {
std :: cin >> a[j];
sum += a[j];
}
for(int j = 1; j <= s[i]; j++)
for(int k = sum / 2; k >= a[j]; k--)
dp[k] = max(dp[k], dp[k - a[j]] + a[j]);
ans += sum - dp[sum / 2];
}
std :: cout << ans << std :: endl;
return 0;
}
評価結果
AC 100:R32745565