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<iostream>
#include<vector>
using namespace std;

struct soba{
	double gram;
	double yen;
	soba(double g, double y){gram=g;yen=y;}
};

double n;
double min_y;
vector<soba> v;


void buy(double sum_g, double sum_y){
	int len = v.size();
	for(int i=0;i < len;i++){
		if(sum_g == n){
			min_y = min(min_y, sum_y);
			return;
		}else if(sum_g > n){
			break;
		}
		buy(sum_g+v[i].gram, sum_y+v[i].yen);
	}
	return;
}


int main(){
	int sum_g, sum_y;
	v.push_back(soba(200,380));
	v.push_back(soba(200*5, (380*5) * 0.8));
	v.push_back(soba(300,550));
	v.push_back(soba(300*4, (550*4) * 0.85));
	v.push_back(soba(500,850));
	v.push_back(soba(500*3, (850*3) * 0.88));
	while(true){
		cin>>n; if(n==0) break;
		min_y = DBL_MAX;
		buy(0,0);
		cout<<int(min_y)<<endl;
	}
	return 0;
}

C++: #include <cstdio>

int w[] = { 2, 3, 5, 10, 12, 15 };
int v[] = { 380, 550, 850, 1520, 1870, 2244 };
int n = 6;
#define M 50
#define INF 10000000
#define min(x, y) ((x) < (y) ? (x) : (y))
int dp[M+10];

int main()
{
	for (int i = 0; i <= M; ++i) dp[i] = INF;
	for (int i = 0; i < n; ++i) dp[w[i]] = v[i];

	for (int i = 6; i <= M; ++i)
		for (int j = 0; j < n; ++j)
			for (int k = 1; k * w[j] <= i; ++k)
				dp[i] = min(dp[i], dp[i-k*w[j]] + k*v[j]);

	int m;
	while (scanf("%d", &m), m) printf("%d\n", dp[m/100]);
	return 0;
}

C++: #include <iostream>
#include <string>
#include <algorithm>
#include <functional>
#include <vector>
#include <utility>
#include <cstring>
#include <iomanip>
#include <numeric>
#include <cmath>
#include <queue>
#include <map>
using namespace std;
typedef long long ll;
const int INF = 1<<30; 
const int MOD = 1e9 + 7;
const int dy[] = {1, 0, -1, 0};
const int dx[] = {0, 1, 0, -1};
int n, ans;
int main()
{
    cin.tie(0);
    ios::sync_with_stdio(false);
    while(cin >> n, n)
    {
        ans = INF;
        for(int i = 0; i < 100; i++)
        {
            for(int j = 0; j < 100; j++)
            {
                int m = n - 200 * i - 300 * j;
                if(m < 0) break;
                int k;
                if(m % 500 == 0) k = m / 500;
                else continue;
                int sum = 0;
                if(i / 5 != 0) sum += 380 * (i - i % 5) * 0.8 + 380 * (i % 5);
                else sum += 380 * i;
                if(j / 4 != 0) sum += 550 * (j - j % 4) * 0.85 + 550 * (j % 4);
                else sum += 550 * j;
                if(k / 3 != 0) sum += 850 * (k - k % 3) * 0.88 + 850 * (k % 3);
                else sum += 850 * k;
                ans = min(ans, sum);
            }
        }
        cout << ans << endl;
    }
    return 0;
}

C++: #include <iostream>
#include <cstdio>
#include <algorithm>

using namespace std;

int Max;

void solve(int n,int k){
  if(n<=0){
    Max=min(k,Max);
    return;
  }
  solve(n-200*5,k+380*0.8*5);
  solve(n-300*4,k+550*0.85*4);
  solve(n-500*3,k+850*0.88*3);
  solve(n-200,k+380);
  solve(n-300,k+550);
  solve(n-500,k+850);
  return;
}

int main(void){
  int n;
  while(cin>>n,n!=0){
    Max=9999999;
    solve(n,0);
    cout<<Max<<endl;
  }
  return 0;
}

C++: #include <stdio.h>
const int N=500;
const int INF=1e9+10;
int min(int a,int b){return a>b?b:a;}
int main(){
    int n,dp[N];
    dp[0]=0;
    for(int i=1;i<N;i++)dp[i]=INF;
    for(int i=0;i<100;i++)dp[i+2]=min(dp[i+2],dp[i]+380);
    for(int i=0;i<100;i++)dp[i+10]=min(dp[i+10],dp[i]+1520);
    for(int i=0;i<100;i++)dp[i+3]=min(dp[i+3],dp[i]+550);
    for(int i=0;i<100;i++)dp[i+12]=min(dp[i+12],dp[i]+1870);
    for(int i=0;i<100;i++)dp[i+5]=min(dp[i+5],dp[i]+850);
    for(int i=0;i<100;i++)dp[i+15]=min(dp[i+15],dp[i]+2244);
    while(true){
        scanf("%d",&n);
        if(n==0)return 0;
        printf("%d\n",dp[n/100]);
    }
}

C++: #include <stdio.h>
#include <string.h>

#define min(a, b) ((a) < (b) ? (a) : (b))

int dp[128];

void solve(int v, int p)
{
    int i;

    for (i = 0; i < 60; i++){
        if (dp[i] == -1) continue;
        if (dp[i + v] == -1) dp[i + v] = dp[i] + p;
        else dp[i + v] = min(dp[i + v], dp[i] + p);
    }
}

int main(void)
{
    int n;
    int i;

    memset(dp, -1, 128 * sizeof(int));
    dp[0] = 0;
    solve(2, 380);
    solve(3, 550);
    solve(5, 850);
    solve(10, 3040);
    solve(12, 1870);
    solve(15, 2244);
    /*
    for (i = 0; i < 5; i++){
        int j;
        for (j = 0; j < 10; j++) printf("%4d ", dp[i * 10 + j]);
        puts("");
    }
    puts("");
    */
    while (scanf("%d", &n), n){
        printf("%d\n", dp[n / 100]);
    }

    return 0;
}

C++: #include<iostream>
#include<algorithm>
#include<vector>
#include<stack>
#include<map>
#include<set>
#include<queue>
#include<cstdio>
#include<climits>
#include<cmath>
#include<cstring>
#include<string>
#include<sstream>

#define f first
#define s second
#define mp make_pair

#define REP(i,n) for(int i=0; i<(int)(n); i++)
#define FOR(i,c) for(__typeof((c).begin()) i=(c).begin(); i!=(c).end(); i++)
#define ALL(c) (c).begin(), (c).end()

using namespace std;

typedef unsigned int uint;
typedef long long ll;

int cost(int a, int b, int c){
  int ret = 0;
  int aa = a % 5; a -= aa;
  int bb = b % 4; b -= bb;
  int cc = c % 3; c -= cc;
  ret += (int)(a * 380 * 0.80) + aa * 380;
  ret += (int)(b * 550 * 0.85 + 0.1) + bb * 550;
  ret += (int)(c * 850 * 0.88) + cc * 850;
  return ret;
}

int main(){
  int n;
  while(cin>>n, n){
    int ans = INT_MAX;
    n /= 100;
    for(int i = 0; i < n + 2; i+=2){
      for(int j = 0; i + j < n + 3; j+=3){
        int k = n - i - j + 4;
        //printf("%d %d %d => %d\n",i/2,j/3,k/5,cost(i/2,j/3,k/5));
        ans = min(ans, cost(i/2,j/3,k/5));
      }
    }
    cout << ans << endl;
  }
  return 0;
}

C++: #include<iostream>
using namespace std;
void recur(int w, int sti, int counts[], int *ans){
	if( w <= 0 ){
		int value;
		int dv[] = {380,550,850};
		value =
			(counts[0] * dv[0] - int((counts[0] / 5) * (5 * dv[0]) * 0.2)) +
			(counts[1] * dv[1] - int((counts[1] / 4) * (4 * dv[1]) * 0.15)) +
			(counts[2] * dv[2] - int((counts[2] / 3) * (3 * dv[2]) * 0.12));
		*ans = min(*ans, value);
	}else{
		int dw[] = {200,300,500};
		for(int i = sti; i < sizeof(dw)/sizeof(*dw); i++){
			w -= dw[i];
			counts[i]++;
			recur(w, i, counts, ans);
			counts[i]--;
			w += dw[i];
		}
	}
}
int main(void){
	while(true){
		int w, ans = 1<<22, cnts[3]={0,};

		cin>>w;
		if(w==0)break;

		recur(w, 0, cnts, &ans);
		cout << ans << '\n';
	}
	return 0;
}

C++: #include <iostream>
#include <algorithm>
int main(){
		int weight[6] = {200,300,500,1000,1200,1500},price[6] = {380,550,850,1520,1870,2244};
		int n;
		while(std::cin >> n,n){
		
			const int INF = 50000;
			int dp[5001] = {0};
			for(int i=1;i<5001;i++){
				dp[i] = INF;
			}
			
			for(int i=0;i<6;i++){
				for(int j=0;j<=n;j++){
					if(j+weight[i] <= n)
						dp[j+weight[i]] = std::min(dp[j+weight[i]],dp[j]+price[i]);
				}
			}
			
			std::cout << dp[n] << std::endl;
		}
}