Go: package main

import "fmt"

func main() {
	maxGram := 5000
	// store := map[int]int{
	// 	1500: 2244, // 500 * 3
	// 	1200: 1870, // 300 * 4
	// 	1000: 1520, // 200 * 5
	// 	500:  850,
	// 	300:  550,
	// 	200:  380,
	// }

	for {
		var gram int
		fmt.Scanf("%d", &gram)

		if gram == 0 {
			return
		}

		var minPrice int

		// (x * 200) + (y * 300) + (z * 500) == gram
		for x := 0; (x * 200) <= maxGram; x++ {
			for y := 0; (y * 300) <= maxGram; y++ {
				for z := 0; (z * 500) <= maxGram; z++ {
					if (x*200)+(y*300)+(z*500) == gram {
						price := 0
						price += (z / 3) * 2244
						price += (z % 3) * 850
						price += (y / 4) * 1870
						price += (y % 4) * 550
						price += (x / 5) * 1520
						price += (x % 5) * 380

						if price < minPrice || minPrice == 0 {
							minPrice = price
						}
					}
				}
			}
		}

		fmt.Println(minPrice)
	}
}

// 1 袋あたりの量			200g	300g	500g
// 1 袋の単価(定価)		380円	550円	850円
// 割引が適用される単位		5袋毎	4袋毎	3袋毎
// 割引率							20%引き	15%引き	12%引き

C++: //
//  main.cpp
//  main
//
//  Created by h3037175 on 2018/01/25.
//  Copyright © 2018年 h3037175. All rights reserved.
//

#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;
        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(n/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<cstring>
#include<algorithm>
using namespace std;
int n;
int memo[32][32][32];
int solve(int a, int b, int c){
  if(memo[a][b][c]) return memo[a][b][c];
  if(a * 200 + b * 300 + c * 500 > n) return 999999999;
  if(a * 200 + b * 300 + c * 500 == n) return 0;
  int ret = 999999999;
  ret = min(ret, min(solve(a + 1, b, c) + 380, solve(a + 5, b, c) + (int)(380 * 5 * 0.8)));
  ret = min(ret, min(solve(a, b + 1, c) + 550, solve(a, b + 4, c) + (int)(550 * 4 * 0.85)));
  ret = min(ret, min(solve(a, b, c + 1) + 850, solve(a, b, c + 3) + (int)(850 * 3 * 0.88)));
  return memo[a][b][c] = ret;
}
int main(void){
  for( ; ; ){
    scanf("%d", &n);
    if(!n) break;
    memset(memo, 0, sizeof(memo));
    printf("%d\n", solve(0, 0, 0));
  }
}

C++: #include<iostream>
using namespace std;
#define INF (1<<30)-1
int main(){
  int s[6]={2,3,5,10,12,15};
  int n[6]={380,550,850,1520,1870,2244};
  int m;
  while(cin>>m){
    if(m==0) break;
    m /= 100;
    int dp[m+1];
    for(int i=0;i<=m;i++) dp[i] = INF;
    dp[0] = 0;
    for(int i=5;i>=0;i--){
      for(int j=0;j<=m;j++){
	if(j+s[i]<=m&&dp[j]!=INF) dp[j+s[i]] = min(dp[j+s[i]],dp[j]+n[i]);
      }
    }
    cout << dp[m] << endl;
  }
  return 0;
}

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

typedef long long ll;
typedef vector<int> vint;
typedef vector<long long> vll;
typedef pair<int,int> pint;
typedef pair<long long, long long> pll;

#define MP make_pair
#define PB push_back
#define ALL(s) (s).begin(),(s).end()
#define EACH(i, s) for (__typeof__((s).begin()) i = (s).begin(); i != (s).end(); ++i)
#define COUT(x) cout << #x << " = " << (x) << " (L" << __LINE__ << ")" << endl

template<class T> inline bool chmax(T& a, T b) { if (a < b) { a = b; return 1; } return 0; }
template<class T> inline bool chmin(T& a, T b) { if (a > b) { a = b; return 1; } return 0; }
template<class T1, class T2> ostream& operator << (ostream &s, pair<T1,T2> P) 
{ return s << '<' << P.first << ", " << P.second << '>'; }
template<class T> ostream& operator << (ostream &s, vector<T> P) 
{ for (int i = 0; i < P.size(); ++i) { if (i > 0) { s << " "; } s << P[i]; } return s; }
template<class T> ostream& operator << (ostream &s, vector<vector<T> > P) 
{ for (int i = 0; i < P.size(); ++i) { s << endl << P[i]; } return s << endl; }
template<class T1, class T2> ostream& operator << (ostream &s, map<T1,T2> P) 
{ EACH(it, P) { s << "<" << it->first << "->" << it->second << "> "; } return s; }



int n;

int main() {
    while (cin >> n) {
        if (n == 0) break;
        int res = 1<<29;
        for (int a = 0; a <= 25; ++a) for (int b = 0; b <= 20; ++b) for (int c = 0; c <= 10; ++c) {
            int tot = a * 200 + b * 300 + c * 500;
            if (tot != n) continue;
            int s1 = 380 * (a / 5) * 5 * 4/5 + 380 * (a % 5);
            int s2 = 550 * (b / 4) * 4 * 17/20 + 550 * (b % 4);
            int s3 = 850 * (c / 3) * 3 * 22/25 + 850 * (c % 3);
            
            //cout << a << ", " << b << ", " << c << " : " << s1+s2+s3 << endl;
            
            chmin(res, s1+s2+s3);
        }
        cout << res << endl;
    }
    return 0;
}

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

int w[]={2,3,5,10,12,15};
int v[]={380,550,850,1520,1870,2244};
 
int dp[50+1];
void solve(){
    for(int i=0;i<51;i++){
        dp[i]=INT_MAX/3;
    }
    dp[0]=0;
    for(int i=0;i<6;i++){
        for(int j=w[i];j<=50;j++){
            dp[j]=min(dp[j],dp[j-w[i]]+v[i]);
        }
    }
}
 
int main(){
    solve();
    int n;
    while(cin>>n){
        if(n==0)break;
        n/=100;
        cout<<dp[n]<<endl;
    }
  return 0;
}

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

const int MAX_WEIGHT = 5000;
const int MIN_WEIGHT = 500;

struct Comodity{
	int weight, price, unit;
	double rate;
};

Comodity com_list[] = {
	{ 200, 380, 5, 0.8 },
	{ 300, 550, 4, 0.85 },
	{ 500, 850, 3, 0.88 },
};

enum{
	A,
	B,
	C,
};

int quantity( int remain, int unit_weight ){
	return remain > 0 ? remain / unit_weight + ( remain % unit_weight ? 1 : 0 ) : 0;
}

int calcPrice( int a, int b, int c ){
	int dis_a = a / com_list[ A ].unit * com_list[ A ].unit;
	int dis_b = b / com_list[ B ].unit * com_list[ B ].unit;
	int dis_c = c / com_list[ C ].unit * com_list[ C ].unit;
	a -= dis_a;
	b -= dis_b;
	c -= dis_c;
	return ( a * com_list[ A ].price ) + ( b * com_list[ B ].price ) + ( c * com_list[ C ].price )
		+ (int)( dis_a * com_list[ A ].price * com_list[ A ].rate )
		+ (int)( dis_b * com_list[ B ].price * com_list[ B ].rate )
		+ (int)( dis_c * com_list[ C ].price * com_list[ C ].rate );
}

int main()
{
	int weight;

	while( cin >> weight && weight ){
		int best_price = INT_MAX;
		int remain_a = weight;
		int a = quantity( remain_a, com_list[ A ].weight );
		for( ; a >= 0; --a ){
			int remain_b = remain_a - a * com_list[ A ].weight;
			int b = quantity( remain_b, com_list[ B ].weight );
			for( ; b >= 0; --b ){
				int remain_c = remain_b - b * com_list[ B ].weight;
				int c = quantity( remain_c, com_list[ C ].weight );
				best_price = min( best_price, calcPrice( a, b, c ) );
			}
		}
		cout << best_price << endl;
	}

	return 0;
}