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 <algorithm>
using namespace std;

int w;
int dp[15];
int ans;
const int g[3] = {2, 3, 5};
const int v[3] = {380, 550, 850};
const int n[3] = {5, 4, 3};
const double t[3] = {0.8, 0.85, 0.88};
void rec1(int p, int value, int weight) {
  bool flag = false;
  for(int i = p; i < 3; ++i) {
    if(weight + g[i]*n[i] <= w) {
      rec1(i, value + (int)(v[i]*n[i]*t[i]+0.5), weight + g[i]*n[i]);
    } else {
      flag = true;
    }
  }
  if(flag) ans = min(ans, value + dp[w - weight]);
}

void solve() {
  w /= 100;
  ans = 99999999;
  rec1(0, 0, 0);
  cout << ans << endl;
}

void make() {
  dp[0] = 0;
  for(int i = 1; i <= 14; ++i) {
    dp[i] = 99999999;
    for(int j = 0; j < 3; ++j) {
      if(i-g[j] >= 0) dp[i] = min(dp[i], v[j] + dp[i-g[j]]);
    }
  }
}

main() {
  make();
  while((cin >> w) && w) solve();
}

C++: #include <cstdio>
#include <cstdlib>
#include <cmath>
#include <climits>
#include <cfloat>
#include <cstring>
#include <map>
#include <utility>
#include <set>
#include <iostream>
#include <memory>
#include <string>
#include <vector>
#include <algorithm>
#include <functional>
#include <sstream>
#include <fstream>
#include <complex>
#include <stack>
#include <queue>

using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
static const double EPS = 1e-5;

#define FOR(i,k,n) for (int i=(k); i<(int)(n); ++i)
#define REP(i,n) FOR(i,0,n)
int d[6] = {1500,1200,1000,500,300,200};
int m[6] = {2244,1870,1520,850,550,380};
int main(void){
  int n;
  int dp[5001]={0};
  FOR(i,1,5001) dp[i] = 1e8;
  REP(i,6){
    FOR(j,0,5001-d[i]){
      dp[j+d[i]] = min(dp[j] + m[i], dp[j+d[i]]);
    }
  }
  while(cin>>n){
    if(!n) break;
    cout<<dp[n]<<endl;
  }
  return 0;
}

C++: #include <iostream>
#include <vector>
#include <string>
#include <stack>
#include <queue>
#include <deque>
#include <set>
#include <map>
#include <algorithm>	// require sort next_permutation count etc.
#include <cstdlib>	// require abs
#include <cstdio>	// require printf
#include <functional>
#include <numeric>	// require accumulate
#include <cmath>
#include <climits>
#include <limits>
#include <cfloat>
#include <iomanip>	// require setw
#include <sstream>	// require stringstream 
#include <cstring>	// require memset
#include <cctype>	// require tolower, toupper
#include <fstream>	// require freopen

using namespace std;
const double INF = (double)(1 << 20);
const int g[3] = { 200, 300, 500 };
const int t[3] = { 380, 550, 850 };
const int d[3] = { 5, 4, 3 };
const int r[3] = { 80, 85, 88 };

double dp[3][5001];			// gツづ個値ツ段ツ、
double minc[5001];

void calc (int gram )
{
	for (int i = 0; i <= 5000; i += g[0] ){
		for (int j = 0; j <= 5000; j += g[1] ) {
			for (int k = 0; k <= 5000; k += g[2] ){
				if (gram == i + j + k ){
					minc[gram] = min (minc[gram], dp[0][i] + dp[1][j] + dp[2][k] );
				} // end if
			} // end for
		} // end for
	} // end for
}

int main()
{
//	cut here before submit 
//	freopen ("testcase.DB", "r", stdin );
	for (int i = 0; i <= 5000; i++ ){
		for (int j = 0; j < 3; j++ ){
			dp[j][i] = INF;
		} // end for
	} // end for
	for (int j = 0; j < 3; j++ )
		dp[j][0] = 0.;

	for (int j = 0; j < 3; j++ ){
		for (int i = g[j], k = 1; i <= 5000; i += g[j], k++ ){
			dp[j][i] = dp[j][i-g[j]] + (double)t[j];
			if (k % d[j] == 0 ){
				if (k/d[j] == 1 ){
					dp[j][i] *= (double)r[j];
					dp[j][i] /= 100.;
				}else{
					dp[j][i] = dp[j][d[j]*g[j]]*(double)k/d[j];
				} // end if
			} // end if 
		} // end for
	} // end for

	for (int i = 0; i <= 5000; i++ ){
		minc[i] = INF;
	} // end for
	for (int i = 500; i <= 5000; i += 100 ){
		calc (i );
	} // end for

//	for (int i = 500; i <= 5000; i += 100 ){
//		cout << setw(4) << i << ':' << setw(4) << minc[i] << endl;
//	} // end for

	int n;
	while (cin >> n, n ){
		int res = minc[n];
		cout << res << endl;
	} // end while

/*
	for (int i = 0; i < 3; i++ ){
//	int i = 0;
		for (int j = 0; j <= 5000; j++ ){
			if (dp[i][j] != INF ){
				cout << "i: " << i << " j: " << setw(4) << j << " price: " << dp[i][j] << endl;
			} // end if
		} // end for
	} // end for 
*/		
	return 0;
}

C++: #include <iostream>
#define MAX_P 1000000
using namespace std;
int g;
int minx=0;
void price(int a,int b,int c){
	if(a/5*1520+a%5*380+b/4*1870+b%4*550+c/3*2244+c%3*850<minx)
		minx=a/5*1520+a%5*380+b/4*1870+b%4*550+c/3*2244+c%3*850;
	return; 
}

void shop(int g,int a,int b,int c){
	if(g==0){
		price(a,b,c);
		return;
	}else if(g<0){
		return;
	}
	shop(g-200,a+1,b,c);
	shop(g-300,a,b+1,c);
	shop(g-500,a,b,c+1);
	return;
}

int main(){
	while(1){
		cin >> g;
		if(g==0)break;
		minx=MAX_P;	
		shop(g,0,0,0);
		cout << minx << endl;
	}
	return 0;
}

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

#define INF 1000000007
#define min(a,b) (a>b?b:a)

int lst[6][2] = {
	{ 2, 380},
	{ 3, 550},
	{ 5, 850},
	{10, 1520},
	{12, 1870},
	{15, 2244}
};
#define M 50
int dp[M+1];

int main() {
	int n;
	for(int i=0; i<=M; ++i) dp[i] = INF;
	dp[0] = 0;
	for(int i=1; i<=M; ++i) {
		for(int j=0; j<6; ++j) {
			if(i>=lst[j][0]) dp[i] = min(dp[i], dp[i-lst[j][0]]+lst[j][1]);
		}
		cout << dp[i] << endl;
	}
	while(cin >> n && n) cout << dp[n/100] << endl;
	return 0;
}

C++: #include<iostream>
#include<algorithm>
#define INF 1<<28
using namespace std;
 
int memo[10000];
 
int solve(int n){

  if(!n) return 0;
  if(n < 0) return INF;
  if(memo[n]) return memo[n];

  return memo[n] = min(INF, min(solve(n-1000)+1520, min(solve(n-1200)+1870, min(solve(n-1500)+2244, min(solve(n-200)+380, min(solve(n-300)+550, solve(n-500)+850))))));
}
 
int main(){
  int n;
  for(int i=0;i<5001;i+=100) solve(i);
  while(cin >> n, n) cout << memo[n] << endl;
}

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

int main(){
  int g;
  int dp[3][51];

  
  for(int i=0;i<51;i++){
    int tmp = i/2;
    if(i>2*tmp)tmp++;
    dp[0][i] = (tmp/5) * 1520 + (tmp%5) * 380;
  }

  for(int i=0;i<51;i++){
    dp[1][i] = dp[0][i];
    for(int j=1;j<=i;j++){
      int tmp = j/3;
      if(j>3*tmp)tmp++;
      dp[1][i] = min(dp[1][i],dp[0][i-j] + (tmp/4)  * 1870 + (tmp%4) * 550);
    }
  }

  for(int i=0;i<51;i++){
    dp[2][i] = dp[1][i];
    for(int j=1;j<=i;j++){
      int tmp = j/5;
      if(j>5*tmp)tmp++;
      dp[2][i] = min(dp[2][i],dp[1][i-j] + (tmp/3) * 2244 + (tmp%3) * 850);
    }
  }
  /*
  for(int i=0;i<51;i++){
    cout << i << ":" << dp[0][i] << endl;
    if(dp[2][i] > 2 * dp[2][(i+1)/2] ) cout << i << ":error" << endl;
  }
  */
  while(1){
    cin >> g;
    if(!g)break;

    if(g!=(g/100)*100){
      int a = 0;
      cout << g/a << endl;
    }
    cout << dp[2][g/100] << endl;
  }
}