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 <climits>
#include <iostream>
#include <vector>

using namespace std;

double cal_cost(int w, int t) {
  vector<vector<int>> params = {
      {200, 380, 5, 20}, {300, 550, 4, 15}, {500, 850, 3, 12}};
  int cost = INT_MAX;
  int a = params[t][0];
  int b = params[t][1];
  int c = params[t][2];
  int d = params[t][3];
  return (w / a / c) * c * b * (100. - d) / 100. +
         (w - w / a / c * c * a) * double(b) / a;
}

int main() {
  int w;
  while (cin >> w, w) {
    double cost = 1e10;
    for (int a = 0; a <= w; a += 200) {
      for (int b = 0; b <= w; b += 300) {
        for (int c = 0; c <= w; c += 500) {
          if (a + b + c != w)
            continue;
          double tmp = cal_cost(a, 0) + cal_cost(b, 1) + cal_cost(c, 2);
          cost = (tmp < cost) ? tmp : cost;
        }
      }
    }
    cout << cost << 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;
    printf("%d\n", data[n/100]);
  }
}

C++: #include<iostream>
#include<algorithm>
#define INF (1<<24)
using namespace std;
int n,ans;
int checkA(int);
int checkB(int);
int checkC(int);

int main(){
  while(cin>>n&&n){
    ans=INF;
    for(int i=0;i<100;i++){
      for(int j=0;j<100;j++){
	for(int k=0;k<100;k++){
	  if(i*200+j*300+k*500>=n){	    
	    ans=min(checkA(i)+checkB(j)+checkC(k),ans);
	    break;
	  }
	}
      }
    }    
    cout<<ans<<endl;
  }
  return 0;
}
int checkA(int cnt){
  int x = cnt / 5, y = cnt % 5;
  return x*1520+y*380;
}

int checkB(int cnt){
  int x = cnt / 4, y = cnt % 4;
  return x*1870+y*550;
}

int checkC(int cnt){
  int x = cnt / 3, y = cnt % 3;
  return x*2244+y*850;
}

C++: #include <stdio.h>
#include <iostream>
#include <stdlib.h>
#include <vector>

using namespace std;

int s=99999999;

void kakerukamosirenai(int total,int left,int a,int b,int c){
	if(left>0){
		kakerukamosirenai(total+380,left-200,a+200,b,c);//a
		kakerukamosirenai(total+550,left-300,a,b+300,c);//b
		kakerukamosirenai(total+850,left-500,a,b,c+500);//c
	}else if(left==0){
		int cnt=0;
		while(a>=1000){
			a-=1000;
//			total -= 380;
			cnt++;
		}
		total-=(float)(1900*cnt)*20/100;
		cnt=0;

		while(b>=1200){
			b-=1200;
//			total -= 330;
			cnt++;
		}
		total-=(2200*cnt)*15/100;
		cnt=0;

		while(c>=1500){
			c-=1500;
//			total -= 306;
			cnt++;
		}
		total-=(2550*cnt)*12/100;

		if(s>total){
			s = total;
		}
	}else{
//		cout << "erratta" <<endl;
	}
}

int main(){

	vector<int> p;
	int n,c=0,a,t;

	while(1){
		c++;
		cin >> n;
		p.push_back(n);
		if(p[c]==0)break;
	}

	for(int i=0;i<c-1;i++){
		kakerukamosirenai(0,p[i],0,0,0);
		cout << s << endl;
		s = 999999999;
	}

	return 0;
}

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

int dp[100];
int cost[6] = {380, 550, 850, 1520, 1870, 2244};
int amo[6] = {2, 3, 5, 10, 12, 15};

int main() {
    for(int i=0; i<100; ++i) dp[i] = 1<<29;
    dp[0] = 0;

    for(int i=0; i<6; ++i)
        for(int j=0; j+amo[i]<100; ++j)
            if(dp[j] != 1<<29)
                dp[j+amo[i]] = min(dp[j+amo[i]], dp[j] + cost[i]);

    int n;
    while(cin>>n, n) cout<<dp[n/100]<<endl;
}

C++: #include <iostream>
#include <climits>

void init_nums(int nums[])
{
	nums[0] = nums[1] = nums[2] = 0;
}

int cost(int nums[])
{
	int A = nums[0];
	int B = nums[1];
	int C = nums[2];
	
	int qA = A / 5;
	int rA = A % 5;
	int qB = B / 4;
	int rB = B % 4;
	int qC = C / 3;
	int rC = C % 3;
	
	return 1520 * qA + 380 * rA + 1870 * qB + 550 * rB + 2244 * qC + 850 * rC;
}

int minCost(int a, int nums[])
{
	if (a==0) return cost(nums);
	
	int res = INT_MAX;
	
	if (a>=500) {
		nums[2]++; 
		res = std::min(res, minCost(a-500, nums));
		nums[2]--;
	}
	if (a>=300) {
		nums[1]++;
		res = std::min(res, minCost(a-300, nums));
		nums[1]--;
	}
	if (a>=200) {
		nums[0]++;
		res = std::min(res, minCost(a-200, nums));
		nums[0]--;
	}
	
	return res;
}

int main()
{
	int a;
	int nums[3];
	while (true) {
		std::cin >> a;
		if (a == 0) break;
		init_nums(nums);
		std::cout << minCost(a, nums) << std::endl;
	}
	return 0;
}

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

int main()
{
	while (1)
	{
		int a;
		cin >> a;
		if (a == 0)break;
		int m, s;
		m = s = 1000000;
		for (int b = 0; b <=a / 200; b++) {
			for (int c = 0; (b * 200 + c * 300) <= a; c++) {
				if ((a - (b * 200 + c * 300)) % 500 != 0)continue;
				m =  (b / 5) * 1520;
				m += (b % 5) * 380;
				m += (c / 4) * 1870;
				m += (c % 4) * 550;
				m += (((a - b * 200 - c * 300) / 500)/3) * 2244;
				m += (((a - b * 200 - c * 300) / 500) % 3) * 850;
				if (m < s)s = m;
			}
		}
		cout << s << endl;
	}
}

C++: #include <iostream>
#include <vector>
using namespace std;
#define rep(i,n) for(int i=0;i<n;i++)
int  dp[5001];
bool able[5001];

void init(){
	vector<int> item;
	item.push_back(200);
	item.push_back(300);
	item.push_back(500);
	item.push_back(1000);
	item.push_back(1200);
	item.push_back(1500);
	vector<int> price;
	price.push_back(380);
	price.push_back(550);
	price.push_back(850);
	price.push_back(380*5*0.8);
	price.push_back(550*4*0.85);
	price.push_back(850*3*0.88);
	rep(i,5001)dp[i]=(1<<21);
	able[0]=true;
	dp[0]=0;
	for(int k=0;k<item.size();k++){	
		for(int i=0;i+item[k]<=5000;i++){
			able[i+item[k]] = able[i+item[k]] | able[i];
			if(able[i+item[k]]){
				dp[i+item[k]] = min( dp[i+item[k]] , dp[i]+price[k] );
			}
		}
	}
	return;
}

int main(){
	init();
	int n;
	while(cin >> n && n){
		int mi = dp[n];
		for(int i=2200;i<=2800;i+=50){
			mi = min(mi,dp[i]);
		}
		cout << mi << endl;
	}
}