プログラミングの美しさ:第1章1.4本を買う問題


/*本を買う問題:
プロセス:入力を受け入れ、入力を大から小に並べ替え(a,b,c,d,e)、minを選択し、再帰出口を全0に設定します.
入力:2 1 1 1 1 2 2 2 1 2 2 2 2 2 2 10 10 10 10出力:38.0 51.2 60.0 300.0*/
/*キー:1 int_iCostArr[MAXSIZE][MAXSIZE][MAXSIZE][MAXSIZE][MAXSIZE];//メモリ検索として、5次元配列2 void my_を設定できます.sort(int&a,int&b,int&c,int&d,int&e)/これらの値が戻ってから引き続き使用するので、a=_を参照してください.iSortArr[0];//注意再びaを返すので、パラメータは3 my_を参照してください.sort(a,b,c,d,e);//大きいから小さい順にint&iRet=iCostArr[a][b][c][d][e];//なお、ここではリファレンスを使用すると、速度を上げることができ、iResでcostにif(iRet!=-1)/記憶化検索を付与し、すでに解いた場合は直接返します.再帰{return iRet;4 if(a>=1&&b<1)//本が1種類しか残っていない場合、最大値はもちろん、割引がなく、自分で5 else if(a>=1&&e>=1)//a,b,c,d,eが残り、7.5割引{return iRet=min(5*8*75+buyBook(a-1,b-1,c-1,d-1,e-1),4*8*80+buyBook(a-1,b-1,c-1,c-1,d-1)を楽しむことができます. ,    3*8*90 + buyBook(a-1,b-1,c-1,d,e),2*8*95 + buyBook(a-1,b-1,c,d,e) ,    800 + buyBook(a-1,b,c,d,e)); */
#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <iostream>
#include <assert.h>
using namespace std;

const int MAXSIZE = 15;
int _iCostArr[MAXSIZE][MAXSIZE][MAXSIZE][MAXSIZE][MAXSIZE];//       ,      5   
int _iSortArr[5];

bool compare(int a,int b)
{
 return a > b;
}

void my_sort(int& a,int& b,int& c,int& d,int& e)//            ,      
{
 _iSortArr[0] = a;
 _iSortArr[1] = b;
 _iSortArr[2] = c;
 _iSortArr[3] = d;
 _iSortArr[4] = e;
 sort(_iSortArr,_iSortArr+5,compare);
 a = _iSortArr[0];//       a,        
 b = _iSortArr[1];
 c = _iSortArr[2];
 d = _iSortArr[3];
 e = _iSortArr[4];
}

int min(int a,int b)
{
 return a < b ? a : b;
}

int min(int a,int b,int c)
{
 return min( min(a,b),c);
}

int min(int a,int b,int c,int d)
{
 return min(min(a,b),min(c,d));
}

int min(int a,int b,int c,int d,int e)
{
 return min( e,min( min(a,b) , min(c,d) ) );
}

int buyBook(int a,int b,int c,int d,int e)
{
 assert(a >= 0 && b >= 0 && c >= 0 && d >= 0 && e >=0);
 if(!a &&  !b && !c && !d && !e)//    ,       0 ,          0
 {
  return 0;
 }
 my_sort(a,b,c,d,e);//        
 int& iRet = _iCostArr[a][b][c][d][e];//  ,      ,      ,    iRes cost  
 if(iRet != -1)//     ,       ,     ,      
 {
  return iRet;
 }
 //           ,           
 if(a >= 1 && b < 1)//            ,         ,    ,    
 {
  return iRet = (800 + buyBook(a-1,b,c,d,e));
 }
 else if(a >= 1 && b >= 1 && c < 1)//  a b   ,       ,    95 
 {
  return iRet =  min( 2*8*95 + buyBook(a-1,b-1,c,d,e) , 800 + buyBook(a-1,b,c,d,e));
 }
 else if(a >= 1 && c >= 1 && d < 1)//  a,b,c    ,   9 
 {
  return iRet =  min( 3*8*90 + buyBook(a-1,b-1,c-1,d,e), 2*8*95 + buyBook(a-1,b-1,c,d,e) ,
   800 + buyBook(a-1,b,c,d,e) );
 }
 else if(a >= 1 && d >= 1 && e < 1)//a,b,c,d,   ,   8 
 {
  return iRet =  min( 4*8*80 + buyBook(a-1,b-1,c-1,d-1,e) , 3*8*90 + buyBook(a-1,b-1,c-1,d,e),
   2*8*95 + buyBook(a-1,b-1,c,d,e) , 800 + buyBook(a-1,b,c,d,e));
 }
 else if(a >= 1 && e >= 1)//a,b,c,d,e    ,    7.5 
 {
  return iRet =  min(5*8*75 + buyBook(a-1,b-1,c-1,d-1,e-1), 4*8*80 + buyBook(a-1,b-1,c-1,d-1,e) ,
   3*8*90 + buyBook(a-1,b-1,c-1,d,e),2*8*95 + buyBook(a-1,b-1,c,d,e) , 
   800 + buyBook(a-1,b,c,d,e));
 }
 else
 {
 }
}

int butBook_memory(int a,int b,int c,int d,int e)//     ,       ,           
{
 assert(a >= 0 && b >= 0 && c >= 0 && d >= 0 && e >=0);
 if(!a &&  !b && !c && !d && !e)//    ,       0 ,          0
 {
  return 0;
 }
}

void process()
{
 int i = 0;
 while(EOF != scanf("%d %d %d %d %d",&_iSortArr[i],&_iSortArr[i+1],&_iSortArr[i+2],
  &_iSortArr[i+3],&_iSortArr[i+4]))
 {
  memset(_iCostArr,-1,sizeof(_iCostArr));
  int iRes = buyBook(_iSortArr[i],_iSortArr[i+1],_iSortArr[i+2],
   _iSortArr[i+3],_iSortArr[i+4]);
  printf("%.1f
",iRes*1.0/100.0); } } int main(int argc,char* argv[]) { process(); getchar(); return 0; }