Go: package main

import (
	"bufio"
	"fmt"
	"os"
	"strconv"
)

const qA, qB, qC = 200, 300, 500
const pA, pB, pC = 380, 550, 850
const dA, dB, dC = 5, 4, 3

func main() {
	stdin := bufio.NewScanner(os.Stdin)
	for stdin.Scan() {
		q, _ := strconv.Atoi(stdin.Text())
		if q == 0 {
			break
		}

		// A 0袋から始める
		curPrice, newPrice := 0, 0
		// B
		for a := 0; a <= int(q/qA); a++ {
			for b := 0; b <= int((q-qA*a)/qB); b++ {
				// 残り
				rem := q - qA*a - qB*b
				if rem == 0 || ((rem > 0) && ((rem % qC) == 0)) {
					// ちょうど買える
					newPrice = amount(a, b, int(rem/qC))
					if curPrice == 0 || newPrice < curPrice {
						// println(a, b, int(rem/qC), newPrice)
						curPrice = newPrice
					}
				}
			}
		}
		fmt.Println(curPrice)
	}
}

func amount(a, b, c int) int {
	tA := int(float64(int(a/dA)*dA*pA)*0.8) + (a%dA)*pA
	tB := int(float64(int(b/dB)*dB*pB)*0.85) + (b%dB)*pB
	tC := int(float64(int(c/dC)*dC*pC)*0.88) + (c%dC)*pC
	// println("amount:", a, b, c, tA, tB, tC, tA+tB+tC)
	return tA + tB + tC
}

C++: #include <iostream>
#include <sstream>
#include <string>
#include <vector>
#include <set>
#include <map>
#include <stack>
#include <queue>
#include <algorithm>
#include <numeric>
#include <functional>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <climits>
using namespace std;

typedef istringstream ISS;
typedef ostringstream OSS;
typedef vector<string> VS;
typedef int INT;
typedef vector<INT> VI;
typedef vector<VI> VVI;
typedef pair <INT, INT> II;
typedef vector <II> VII;

template<class T> ostream& operator << ( ostream& os, vector<T> v ) {
    for ( typename vector<T>::iterator it_i = v.begin(); it_i != v.end(); ++it_i ) {
        os << *it_i << ", ";
    }
    return os;
}


typedef long long LL;

double calc( int n, double value, int k, double p ) {
    return value * (int)( n / k * k ) * p + ( n % k ) * value;
}

LL solve( int n ) {
    LL res = INT_MAX;
    int W[3] = { 200, 300, 500 };
    int V[3] = { 380, 550, 850 };
    int K[3] = { 5, 4, 3 };
    double P[3] = { 0.8, 0.85, 0.88 };
    for ( int a = 0; a < 100; ++ a ) {
        for ( int b = 0; b < 100; ++ b ) {
            for ( int c = 0; c < 100; ++ c ) {
                int sumW = W[0] * a + W[1] * b + W[2] * c;
                if ( sumW != n ) continue;
                res = min( res,
                           (LL)(calc( a, V[0], K[0], P[0] )
                           + calc( b, V[1], K[1], P[1] )
                            + calc( c, V[2], K[2], P[2] )));
            }
        }
    }
    return res;
}

int main() {
    int n;
    while ( cin >> n && n ) {
        cout << solve( n ) << endl;
    }
    return 0;
}

C++: #include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
int main(){
  int dp[5001];
  int g[] ={200, 300, 500, 1000, 1200, 1500};
  int value[] ={380, 550, 850, 1520, 1870, 2244};

  fill(dp, dp+5001, 1 << 29);
  
  dp[0] = 0;
  
  for(int i = 0 ; i < 6 ; i++){
    for(int j = 0 ; j+g[i] <= 5000 ; j+=100){
      dp[j+g[i]] = min(dp[j+g[i]], dp[j]+value[i]);
    }
  }
  
  int n;
  while(cin >> n, n){
    cout << dp[n] << endl;
  }
  return 0;
}

C++: #include <iostream>
#include<string>
#include<queue>
#include<utility>
#include<algorithm>
#include<math.h>
using namespace std;
int main() {
    int n,sum,p,sump;
    while(1){
        sum=0;
        p=0;
        sump=0;
        cin>>n;
        p=n;
        if(n==0)break;
        for(int i=0;i<2;++i){
            if(i==0){
                if(n/1200>0){
                    sum+=n/1200*550*4*0.85;
                    n-=(n/1200)*1200;
                }
                if(n/1000>0){
                    sum+=n/1000*380*5*0.8;
                    n-=(n/1000)*1000;
                    }
                }
            else{
                if(p/1500>0){
                    sump+=p/1500*850*3*0.82;
                    p-=(p/1500)*1500;
                }
            }
        }
        sum=max(sump,sum);
        if(sum==sump&&sum!=0){
            n=p;
        }
        if(n>=500){
            sum+=n/500*850;
            n-=(n/500)*500;
        }
        if(n>=300){
            sum+=n/300*550;
            n-=(n/300)*300;
        }
        if(n>=200){
            sum+=n/200*380;
            n-=(n/200)*200;
        }
        cout<<sum<<endl;
        
    }
    
    return 0;
}

C++: #include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <ctime>
#include <cassert>
#include <iostream>
#include <cctype>
#include <sstream>
#include <string>
#include <list>
#include <vector>
#include <queue>
#include <set>
#include <stack>
#include <map>
#include <utility>
#include <numeric>
#include <algorithm>
#include <iterator>
#include <bitset>
#include <complex>
#include <fstream>
#include <iomanip>
using namespace std;
typedef long long ll;
const double EPS = 1e-9;
typedef vector<int> vint;
typedef pair<int, int> pint;
#define rep(i, n) REP(i, 0, n)
#define ALL(v) v.begin(), v.end()
#define MSG(a) cout << #a << " " << a << endl;
#define REP(i, x, n) for(int i = x; i < n; i++)
template<class T, class C> void chmax(T& a, C b){ if(a < b) a = b; }
template<class T, class C> void chmin(T& a, C b){ if(b < a) a = b; }
template<class T, class C> pair<T, C> mp(T a, C b){ return make_pair(a, b); }


int m[] = {200, 300, 500};
int p[] = {380, 550, 850};
int d[] = {5, 4, 3};
double r[] = {0.8, 0.85, 0.88};
const int INF = 1 << 30;

int dfs(int k, int rest, double x)
{
    if(rest == 0) return x;
    
    if(k == 3 || rest < 0) return INF;
    
    int res = INF;
    rep(i, 41)
        chmin(res, dfs(k + 1, rest - m[k] * i, x + p[k] * (i - i % d[k]) * r[k] + p[k] * (i % d[k])));
    
    return res;
}

int main()
{
	int v;
	while(cin >> v && v)
        cout << dfs(0, v, 0) << endl;
}

C++: #include<iostream>
#include<algorithm>
using namespace std;

int main(){
	int m;
	while(cin>>m&&m){
		int ans=1<<30;
		for(int i=0;i<=m/500;i++){
			int a=i/3*3*850*88/100;
			a += i%3*850;
			for(int j=0;j<=(m-i*500)/300;j++){
				int b=j/4*4*550*85/100;
				b += j%4*550;
				if((m-i*500-j*300)%200)continue;
				int k=(m-i*500-j*300+199)/200,c;
				c=k/5*5*380*80/100;
				c += k%5*380;
				ans=min(ans,a+b+c);
			}
		}
		cout<<ans<<endl;
	}
	return 0;
}

C++: #include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

int main() {
  while(true) {
    int ng;
    cin >> ng;
    if(ng == 0) break;
    vector<int> resultCandidits;
    for(int c = (ng / 500); c >= 0; --c) {
      int leftc = ng - c * 500;
      for(int b = leftc / 300; b >= 0; --b) {
        int leftb = leftc - b * 300;
        if(leftb % 200 == 0 && leftb / 200 >= 0) {
          int a = leftb / 200;
          // cout << (c / 3 * 2244 + c % 3 * 850) + (b / 4 * 1870 + b % 4 * 550) + (a / 5 * 1520 + a % 5 * 380) << endl;
          resultCandidits.push_back((c / 3 * 2244 + c % 3 * 850) + (b / 4 * 1870 + b % 4 * 550) + (a / 5 * 1520 + a % 5 * 380));
          // cout << "c:" << c << ", b:" << b << ", a:" << a << endl;
        }
      }
    }
    cout << *(min_element(resultCandidits.begin(), resultCandidits.end())) << endl;
  }

  return 0;
}

C++: #include <cstdio>
#include <algorithm>
#define INF (1145141919)
using namespace std;

int w[] = {200, 300, 500};
int v[] = {380, 550, 850};
int u[] = {5, 4, 3};
int p[] = {20, 15, 12};
 
int main()
{
	int dp[5001];
	
	for (int i = 1; i <= 5000; i++){
		dp[i] = INF;
	}
	dp[0] = 0;
	
	for (int k = 0; k < 3; k++){
		for (int i = 5000; i >= 0; i--){
			if (dp[i] < INF){
				for (int j = 0; i + j * w[k] <= 5000; j++){
					int yen = dp[i] + v[k] * j;
					yen -= (v[k] * u[k] * p[k] / 100) * (j / u[k]);
					
					dp[i + w[k] * j] = min(dp[i + w[k] * j], yen);
				}
			}
		}
	}
	
	int g;
	while (scanf("%d", &g), g){
		printf("%d\n", dp[g]);
	}
	
	return 0;
}