トピック
10、20、50、100元のコインの金種を使用して、質問で指定された金種を作成します。コインの最小数が必要です
分析
最初、チームメイトはif-elseの束を使用して問題を解決したいと考えていましたが、WAは無数の投稿を行いました...
私はこの問題を解決する比較的簡単な方法を考えました、そしてこのテーブルの長さは13整数
分析を開始する前に、-1と表示されるソリューションについては考慮しません。つまり、この判断は非常に単純であるため、mod 10が0と等しくない場合があります。
法律
この表を推し進める前に明白な法律を決定してください
同じ数のコインを必要とする2つのスキームがあり、最初のスキームの金種を構成できる場合、2番目のスキームは望ましくありません。
証明:最初のプランのセットを使用する場合、2番目のプランを使用できる必要があります。2番目のプランがこれ以上の額面を形成できない場合でも、この選択は完全に正しいです。
推論
法律によれば、以下の推論が得られます
1. 10元を2つ含む計画などはなく、同様に50元も2つは存在しない
証明:2つの10元を含むプランがある場合、このプランを1つの10元と1つの20元に置き換えることを選択できます。2元で10と20の2つの金種しか構成できないと確信できます。そして、10元と20元は10元、20元、30元の3つの金種を形成することができます。法律によると、このスキームは実行不可能であると判断されています。同様に、2つの50元は50 + 100に置き換えることができます
2. 100元以外の4枚のコインのみが使用され、構成スキームは10、20、20、50と20、20、20、50の2つのみです。
証明:4コインの場合、スキーム10、20、20、50は10〜100のすべてのケースを形成できるため、他のスキームが妥当であれば、100元を超えるケースを形成できる必要があります。コロラリー1によれば、50元は繰り返すことができないため、形成できる最大の値は、20、20、20、50を使用して110を形成することです。
3. 100元以外の5コインは使用されません。
証明:まず、5枚のコインを使用した場合、コロラリー1によると、10、20、20、20、50、または120元と、20、20、20、20、50、または130元の2つの組み合わせしか得られません。したがって、組み合わせが何であっても、結果2の結論は10、20、20、50、100の組み合わせほど良くありません。この組み合わせは、すべてのソリューションを10〜200以内で完了することができるためです。次に、法律によれば、上記の2つの組み合わせは間違った組み合わせです。
4. 110元を超える金種は、1枚または数百枚の硬貨で構成する必要があります。
証明:これは非常に単純で、推論3によって直接導出できます。したがって、110元を超える金種の場合は、上記の条件が満たされるまで-100にしてください。
メートル
そして、せいぜい100元ではないコインが4つしかないことを知っているので、すべての組み合わせを取得できます(0は省略)
1
2
5
1 2
1 5
2 2
2 5
1 2 2
1 2 5
2 2 2
2 2 5
1 2 2 5
2 2 2 5
次に、これらの状況が補うことができる数値を入力します
1
2
5
1 2 3
1 5 6
2 4
2 5 7
1 2 3 4 5
1 2 3 5 6 7 8
2 4 6
2 4 5 7 9
1 2 3 4 5 6 7 8 9 10
2 4 6 7 9 11
ビット操作の助けを借りて、これを行うことができます:
print(1 << 1)
print(1 << 2)
print(1 << 5)
print((1 << 1) + (1 << 2) + (1 << 3))
print((1 << 1) + (1 << 5) + (1 << 6))
print((1 << 2) + (1 << 4))
print((1 << 2) + (1 << 5) + (1 << 7))
print((1 << 1) + (1 << 2) + (1 << 3) + (1 << 4) + (1 << 5))
print((1 << 1) + (1 << 2) + (1 << 3) + (1 << 5) + (1 << 6) + (1 << 7) + (1 << 8))
print((1 << 2) + (1 << 4) + (1 << 6))
print((1 << 2) + (1 << 4) + (1 << 5) + (1 << 7) + (1 << 9))
print((1 << 1) + (1 << 2) + (1 << 3) + (1 << 4) + (1 << 5) + (1 << 6) + (1 << 7) + (1 << 8) + (1 << 9) + (1 << 10))
print((1 << 2) + (1 << 4) + (1 << 5) + (1 << 6) + (1 << 7) + (1 << 9) + (1 << 11))
この表の原理を理解してみると、つまり、各バイトはテーブルの要素として使用されます
最大値は110元に過ぎないことがわかります。最大の金種のコインが100であることに注意してください。また、110元は100元以外、または10元+ 100元で構成できます。同様に、100元の組み合わせは2つあります。したがって、4つの状況を考慮する必要があります。1.
100元は100元で構成され、110元は100元で構成されます2、100元は100元で構成されます。110元は
100元
以外で構成されます。3、100元は100元以外で構成されます。110元4の場合は
100元、非100元の場合は100元、非100元の場合は110元を使用します。
次に、すべてについて考えます。どちらか小さい方
ACコード
#include<bits/stdc++.h>
using namespace std;
vector<int> res;
void init() {
res.push_back(0);
res.push_back(2);
res.push_back(4);
res.push_back(32);
res.push_back(14);
res.push_back(98);
res.push_back(20);
res.push_back(164);
res.push_back(62);
res.push_back(494);
res.push_back(84);
res.push_back(692);
res.push_back(2046);
res.push_back(2804);
}
int get_ans(int as) {
int t = -1;
for (int i = 0; i < res.size(); ++i) {
if ((res[i] ^ as) + (res[i] & as) == res[i]) {
t = i;
break;
}
}
switch (t) {
case 0:
return 0;
case 1:
case 2:
case 3:
return 1;
case 4:
case 5:
case 6:
case 7:
return 2;
case 8:
case 9:
case 10:
case 11:
return 3;
case 12:
case 13:
return 4;
}
return 1000;
}
int main() {
#ifdef ACM_LOCAL
freopen("in.txt", "r", stdin);
freopen("out.txt", "w", stdout);
auto start_clock_for_debug = clock();
#endif
ios::sync_with_stdio(false);
cin.tie(0);
cin.tie(0);
int t;
cin >> t;
init();
while (t--) {
int n;
cin >> n;
int hun[4];
int cnt[4][15];
memset(cnt, 0, sizeof(cnt));
memset(hun, 0, sizeof(hun));
bool flag = false;
for (int i = 0; i < n; ++i) {
int tmp;
cin >> tmp;
if (flag) continue;
if (tmp % 10) {
flag = true;
continue;
}
// 100 + 110
int tmp0 = tmp;
if (tmp0 % 100 > 10 and tmp0 > 100) {
hun[0] = max(tmp0 / 100, hun[0]);
tmp0 %= 100;
cnt[0][tmp0 / 10]++;
} else if (tmp0 > 100) {
hun[0] = max((tmp0 - 100) / 100, hun[0]);
tmp0 %= 100;
cnt[0][tmp0 / 10 + 10]++;
} else {
cnt[0][tmp0 / 10]++;
}
// 100
int tmp1 = tmp;
if (tmp1 % 100 == 0 and tmp1 > 100) {
hun[1] = max((tmp1 - 100) / 100, hun[1]);
cnt[1][10]++;
} else {
hun[1] = max(tmp1 / 100, hun[1]);
cnt[1][(tmp1 % 100) / 10]++;
}
// 110
int tmp2 = tmp;
if (tmp2 % 100 == 10 and tmp2 > 100) {
hun[2] = max((tmp2 - 100) / 100, hun[2]);
cnt[2][11]++;
} else {
hun[2] = max(tmp2 / 100, hun[2]);
cnt[2][(tmp2 % 100) / 10]++;
}
// None
int tmp3 = tmp;
hun[3] = max(tmp3 / 100, hun[3]);
cnt[3][(tmp3 % 100) / 10]++;
}
if (flag) {
cout << -1 << endl;
continue;
}
int ans;
int get_ans[4];
for (int j = 0; j < 4; ++j) {
ans = 0;
for (int k = 1; k < 13; ++k) {
if (cnt[j][k]) {
ans += 1 << k;
}
}
get_ans[j] = get_ans(ans) + hun[j];
}
sort(get_ans, get_ans + 4);
cout << get_ans[0] << endl;
}
#ifdef ACM_LOCAL
auto end_clock_for_debug = clock();
cerr << "Run Time: " << double(end_clock_for_debug - start_clock_for_debug) / CLOCKS_PER_SEC << "s" << endl;
#endif
return 0;
}