質問するログイン新規登録

回答編集履歴

3

追記

2018/11/08 12:51

投稿

KSwordOfHaste
KSwordOfHaste

スコア18406

answer CHANGED
@@ -1,3 +1,48 @@
1
+ 追記2: Takahito_Ogawaさんにコメントいただき考えてみるとなるほど再帰的に最適解を求める考え方でよく、一度求めたa, pに関する最適解を複数回計算しなくてよいような論理が容易に組めることに気づけました。コメントありがとうございました。>Takahito_Ogawaさん
2
+
3
+ 既にコードは複数上がっていて本質的には同じことだと思いますが、自分なりの「分かり易い」コードを書いてみました。例えばkichirb3さんのコードは再帰を必要としないコードですが、悲しいかなパっと見てすぐに腑に落ちなかった(^^;)ため自分なりに書いてみたわけです。
4
+
5
+ ```Python
6
+ import math
7
+
8
+ debug_count = 0 # fを何回評価したかの計算量評価用カウンター
9
+
10
+ def f(a, p):
11
+ global debug_count
12
+ debug_count += 1
13
+ return int(math.floor(a * (100 + p) / 100))
14
+
15
+ def solve(a, p):
16
+ assert p > 0
17
+ best = {}
18
+ _count = debug_count
19
+
20
+ def inner(p):
21
+ # 既に(a, p)の最大値が計算済みなら単にそれを返す
22
+ if p in best:
23
+ return best[p]
24
+ # 最初に全てのポイントを一度につぎ込んだ場合を計算
25
+ max_a, max_ps = f(a, p), [p]
26
+ for i in range(1, p):
27
+ # p - iポイントをつぎ込んでからiポイントをつぎ込んだ場合を計算
28
+ # まずp - iポイントをつぎ込んだ場合の最大値・組み合わせを再帰で求め>る
29
+ pre_a, pre_ps = inner(p - i)
30
+ # その後iポイントをつぎ込んだ最終結果を求める
31
+ can_a = f(pre_a, i)
32
+ # 最大値の更新
33
+ if can_a > max_a:
34
+ max_a, max_ps = can_a, pre_ps + [i]
35
+ best[p] = max_a, max_ps
36
+ return best[p]
37
+
38
+ res = inner(p)
39
+ return res + (debug_count - _count,)
40
+
41
+ print(solve(70, 10)) # (77, [10], 55)
42
+ print(solve(10000, 10)) # (11045, [1, 1, 1, 1, 1, 1, 1, 1, 1, 1], 55)
43
+ ```
44
+
45
+ ---
1
46
  追記:Takahito_Ogawaさんの動的計画法をちゃんと理解できてませんが、同じポイントを消費する組み合わせのうち最大のもの以外を候補から手際よく削除しながらベストなものの探索空間を絞り込むというアプローチではないかと思いました。それに対して本回答は劣っていて単にgen_psを示すためだけのものでしかないです。
2
47
 
3
48
  なおポイント数11の最大値は10のときと同じなので1ポイントは無駄ということになり、無暗に組み合わせが増えているだけでありしらみつぶし探索のよくない特徴が浮き彫りになってますね。動的計画法であればこういう影響を受けず本質的に有効な組み合わせを早く求められるのではないかと思います。

2

追記

2018/11/08 12:51

投稿

KSwordOfHaste
KSwordOfHaste

スコア18406

answer CHANGED
@@ -1,3 +1,9 @@
1
+ 追記:Takahito_Ogawaさんの動的計画法をちゃんと理解できてませんが、同じポイントを消費する組み合わせのうち最大のもの以外を候補から手際よく削除しながらベストなものの探索空間を絞り込むというアプローチではないかと思いました。それに対して本回答は劣っていて単にgen_psを示すためだけのものでしかないです。
2
+
3
+ なおポイント数11の最大値は10のときと同じなので1ポイントは無駄ということになり、無暗に組み合わせが増えているだけでありしらみつぶし探索のよくない特徴が浮き彫りになってますね。動的計画法であればこういう影響を受けず本質的に有効な組み合わせを早く求められるのではないかと思います。
4
+
5
+ ---
6
+
1
7
  > 足して10になる組み合わせを全て列挙してリスト化すると言うものですが、まず、それを列挙するアルゴリズムが思いつかない
2
8
 
3
9
  実際には他の回答でのやりとりにあるように単に組み合わせではなく順列を加味した組み合わせになるのでしょうね・・・

1

追記

2018/11/08 02:52

投稿

KSwordOfHaste
KSwordOfHaste

スコア18406

answer CHANGED
@@ -87,4 +87,4 @@
87
87
  ```
88
88
  上の解法は「どういう傾向の組み合わせが最大の価値につながるかが未知」という前提で「全ての組み合わせをしらみつぶしに試す」というアプローチです。
89
89
 
90
- やってみるとポイントが10の場合はベストな組み合わせは2通り、11になると27通りになりました。
90
+ Aの初期値70についてやってみるとポイントが10の場合はベストな組み合わせは2通り、11になると27通りになりました。