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++: #include <algorithm>
#include <cmath>
#include <climits>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <fstream>
#include <iostream>
#include <list>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <vector>
#include <cassert>
#include <functional>

using namespace std;

#define LOG(...) printf(__VA_ARGS__)
//#define LOG(...)
#define FOR(i,a,b) for(int i=(int)(a);i<(int)(b);++i)
#define REP(i,n) for(int i=0;i<(int)(n);++i)
#define ALL(a) (a).begin(),(a).end()
#define RALL(a) (a).rbegin(),(a).rend()
#define EXIST(s,e) ((s).find(e)!=(s).end())
#define SORT(c) sort((c).begin(),(c).end())
#define RSORT(c) sort((c).rbegin(),(c).rend())
#define CLR(a) memset((a), 0 ,sizeof(a))

typedef long long ll;
typedef unsigned long long ull;
typedef vector<bool> vb;
typedef vector<int> vi;
typedef vector<ll> vll;
typedef vector<vb> vvb;
typedef vector<vi> vvi;
typedef vector<vll> vvll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;

const int dx[] = { -1, 0, 1, 0 }; const int dy[] = { 0, 1, 0, -1 };

struct UnionFind {
	vector<int> v;
	UnionFind(int n) : v(n)  { for (int i = 0; i < n; i++) v[i] = i; }
	int  find(int x)         { return v[x] == x ? x : v[x] = find(v[x]); }
	void unite(int x, int y) { v[find(x)] = find(y); }
};
int price[51];
vector<pair<int, int>> soba;
int dfs(int n){
	int mi = 10000;
	if (n == 0)return 0;
	REP(i, 6){
		if (n - soba[i].first == 0 || n - soba[i].first >= 200){
			if (price[(n - soba[i].first) / 100] == 10000)
				mi = min(mi, dfs(n - soba[i].first) + soba[i].second);
			else
				mi = min(mi, price[(n - soba[i].first) / 100] + soba[i].second);
		}
	}
	price[n / 100] = mi;
	return mi;
}
int main() {
	soba.push_back(pair<int, int>(200, 380));//1.9
	soba.push_back(pair<int, int>(300, 550));//18.3
	soba.push_back(pair<int, int>(500, 850));//1.7
	soba.push_back(pair<int, int>(1000, 1520));//1.52
	soba.push_back(pair<int, int>(1200, 1870));//1.55
	soba.push_back(pair<int, int>(1500, 2244));//1.496

	REP(i, 51){
		price[i] = 10000;
	}
	REP(i, 51){
		dfs(i * 100);
	}
	int n;
	while (cin >> n, n){
		cout << price[n / 100] << endl;
	}
}

C++: #include <stdio.h>
#define MIN(a,b) ((a>b)? b:a)
#define INT_MAX (1<<22)

int dp[61];
int data[61];

int search(int remains){
  if(dp[remains]) return data[remains];

  if(remains == 0) return 0;
  if(remains == 1) return INT_MAX;

  int k=INT_MAX;

  if(remains >= 15) k = MIN(k, search(remains-15)+2244);
  if(remains >= 12) k = MIN(k, search(remains-12)+1870);
  if(remains >= 10) k = MIN(k, search(remains-10)+1520);
  if(remains >= 5) k = MIN(k, search(remains-5)+850);
  if(remains >= 3) k = MIN(k, search(remains-3)+550);
  if(remains >= 2) k = MIN(k, search(remains-2)+380);

  dp[remains] = 1;
  return data[remains] = k;
}


int main(){
  int i;
  for(i=0;i<=60;i++) dp[i] = 0, data[i] = 0;

  search(60);
  
  int m = INT_MAX;
  /*for(i=60;i>=0;i--) {
    if(dp[i]) {
      m = data[i] = MIN(data[i], m);
    }else {
      data[i] = m;
    }
  }*/

  int n;
  while(1){
    scanf("%d", &n);
    if(n==0) break;

C++: #include <bits/stdc++.h>

using namespace std;


int TotalCount[3];

int calculation(int a, int b, int c) {
	int totalMoney = 0;

	totalMoney += (a / 5 * 5 * 0.8 + a % 5) * 380;
	totalMoney += (b / 4 * 4 * 0.85 + b % 4) * 550;
	totalMoney += (c / 3 * 3 * 0.88 + c % 3) * 850;

	return totalMoney;
}

int main() {
	int g, minMoney;

	while (cin >> g, g) {
		memset(TotalCount, 0, sizeof(TotalCount));

		TotalCount[0] = g / 200;
		TotalCount[1] = g / 300;
		TotalCount[2] = g / 500;

		minMoney = INT_MAX;
		for (int a = 0; a <= TotalCount[0]; a++) {
			for (int b = 0; b <= TotalCount[1]; b++) {
				for (int c = 0; c <= TotalCount[2]; c++) {
					if (a * 200 + b * 300 + c * 500 == g) {
						minMoney = min(minMoney, calculation(a, b, c));
					}
				}
			}
		}

		cout << minMoney << endl;
	}


	return 0;
}

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

int A(int m) {
	int n = m / 200 + (m % 200 ? 1 : 0);
	int ret = 0;
	ret += (n / 5) * 5 * 380 * 80 / 100;
	ret += n % 5 * 380;
	
	return ret;
}
int B(int m) {
	int n = m / 300 + (m % 300 ? 1 : 0);
	int ret = 0;
	ret += (n / 4) * 4 * 550 * 85 / 100;
	ret += n % 4 * 550;

	return ret;
}
int C(int m) {
	int n = m / 500 + (m % 500 ? 1 : 0);
	int ret = 0;
	ret += (n / 3) * 3 * 850 * 88 / 100;
	ret += n % 3 * 850;

	return ret;
}

int main() {
	int m;
	int table[64];

	for(int i = 0; i < 64; i++) {
		table[i] = A(i * 100);
	}
	for(int i = 63; i >= 0; i--) {
		for(int j = 0; j < i; j++) {
			table[i] = min(table[i], table[i - j] + B(j * 100));
		}
		table[i] = min(table[i], B(i * 100));
	}
	for(int i = 63; i >= 0; i--) {
		for(int j = 0; j < i; j++) {
			table[i] = min(table[i], table[i - j] + C(j * 100));
		}
		table[i] = min(table[i], C(i * 100));
	}

	while(cin >> m, m) {
		cout << table[m / 100 + (m % 100 ? 1: 0)] << endl;
	}

	return 0;
}

C++: //Discounts of Buckwheat
#include<bits/stdc++.h>
using namespace std;
#define INF 10000

int dp[7][51]={0};
int p[6][2]={{2, 380}, {3, 550}, {5, 850}, {10, 1520}, {12, 1870}, {15, 2244}};

void print(){
  for(int i=0; i<7; i++){
    for(int j=0; j<20; j++)
      printf("%6d", dp[i][j]);
    cout<<endl;
  }
}

int main(){
  memset(dp, 0, sizeof(dp));
  for(int i=0; i<51; i++)dp[0][i]=0;

  for(int i=0; i<6; i++){
    for(int j=0; j<51; j++){
      int min_v=INF;
      for(int n=1; ; n++){
        if(j-p[i][0]*n<0)break;
        if(j-p[i][0]*n!=0 && dp[i][j-p[i][0]*n]==0)continue;
        if(min_v>dp[i][j-p[i][0]*n]+p[i][1]*n)
          min_v=dp[i][j-p[i][0]*n]+p[i][1]*n;
      }
      if(dp[i][j]!=0)min_v=min(min_v, dp[i][j]);
      else if(min_v==INF)min_v=0;
      dp[i+1][j]=min_v;
    }
  }
  //print();
  int n;
  while(true){
    cin>>n;
    if(n==0)break;
    cout<<dp[6][n/100]<<endl;
  }
  return 0;
}

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

int main() {
  int combi[100000][3] = {0},m=0;
  int input,price[100000] = {0};
  int a,b,c,a1,b1,c1;

  while(cin >> input) {
    if(input = 0) break;
    for(int i=0;i<26;i++) {//generate combination of weight over input
      for(int j=0;j<17;j++) {
        for(int k=0;k<11;k++) {
          if(input <= 200*i + 300*j + 500*k) {
            combi[m][0] = i;
            combi[m][1] = j;
            combi[m][2] = k;
            m++;
          }
        }
      }
    }

    for(int i=0;i<m;i++) {//calculate price[i] from combi[i]
      a = combi[i][0] / 5;//sale
      a1 = combi[i][0] - a*5;//not sale
      b = combi[i][1] / 4;//sale
      b1 = combi[i][1] - b*4;//not sale
      c = combi[i][2] / 3;//sale
      c1 = combi[i][2] - c*3;//not sale
      price[i] = 1520 * a + 380 * a1 + 1870 * b + 550 * b1 + 2244 * c + 850 * c1;
    }

    sort(price,price+m);

    cout << price[0] << endl;
  }
}