ARC083 C : Sugar Water(300)

作成日:2017.09.17
最終更新日:2017.09.17

問題概要

問題本文

 空のビーカーに水と砂糖を入れ、できるだけ濃度の高い砂糖水を作る。 行える操作は水を100A[g]100A[g]または100B[g]入れることと砂糖をC[g]またはD[g]入れることである。 水100[g]には砂糖はE[g]溶け、ビーカーには水と砂糖合わせてF[g]まで入れられる。 ビーカーに溶け残った砂糖がない時、条件を満たす砂糖水の質量と溶けている砂糖の質量を出力せよ。 答えが複数ある場合はいずれでも良い。
制約
1A<B30
1C<D30
1E100
100AF3000
A,B,C,D,E,Fは整数

考え方

 ある決まった量の水または砂糖を入れることができるかは、少ない量から考えることでO(F)で求められる。 ビーカーに入れる水の量を決めれば、ビーカーから溢れず水に溶けきる最大の砂糖の量もE,Fによって決められる。 また、その量以下で入れることができる最大の量の砂糖を入れることが最善であることは明らかである。 つまり、あり得る水の量をすべて試すことで求める解が得られる。

ソースコード

マクロ等はこちら

  1. const int MC = 3010;
  2. int A,B,C,D,E,F;
  3. bool W[31];
  4. int S[MC];
  5. int ansW,ansS;
  6.  
  7. int main(){
  8. cin >> A >> B >> C >> D >> E >> F;
  9. fill(S,S+MC,-1);
  10. S[0] = 0;
  11. repp(i,0,MC){
  12. if(S[i] < 0){
  13. S[i] = S[i-1];
  14. continue;
  15. }
  16. if(i+C<MC) S[i+C] = i+C;
  17. if(i+D<MC) S[i+D] = i+D;
  18. }
  19. W[0] = 1;
  20. ansW = A;
  21. repp(i,0,31){
  22. if(!W[i]) continue;
  23. if(i+A<31) W[i+A] = 1;
  24. if(i+B<31) W[i+B] = 1;
  25. if(i==0) continue;
  26. if(100*i > F) break;
  27. int tmp = min(S[E*i],F-100*i);
  28. if(ansS * (100*i+tmp) < tmp * (100*ansW + ansS)){
  29. ansW = i;
  30. ansS = tmp;
  31. }
  32. }
  33. cout << 100*ansW+ansS << ' ' << ansS << endl;
  34. return 0;
  35. }

解法まとめ

 ある量以下で入れることができる最大の砂糖の量を求める。(10-18行)
 水の量を決めれば最適な砂糖の入れ方は一意に定まる。 入れることができる水の量をすべて試し、そのうち濃度が最大となるものが解である。(19-33行)

ARC083の他の問題 D E F

自己紹介

プログラミングとか合成音声とか
詳しくはこちら
twitter

プライバシーポリシー

個人情報利用についてはこちら

最終更新日:2023.03.05

お問い合わせ

このページに関するお問い合わせはこちら

競技プログラミングMENU

問題を解くまでの道のり

その他

全体MENU

寄付モドキ

0冂から10000冂まで
詳しくはこちら