最佳购物方案的题目

[问题描述]

在一条街上有n个商店,每个商店有一种商品可卖,有数字代替商品名,商品都有价格,各个商店可卖同一种商品而价格可以不一样,现在又一个人要从街头走到结尾去购物,他手上有一张要购买的商品的清单,现在必须按照清单上的次序依次购买商品( 或者可以不按照清单顺序购买 ) ,求花费最小的购物方法;
例如 购物清单:(数字代替商品名) 2 2 5 1
商店情况:
商店 S1    S2    S3    S4  S5    S6    S7    S8
商品  2      3      2      5    2      5      4      1
价格  50    80    40    60  42    65    100  30


[不按照清单顺序-贪心算法] 花费最小的方法是:S3 S4  S5  S8 === 40+60+42+30=172(一个商店最多购买同类商品一个)

[按照清单的顺序-动态规划] 花费最小的方法是:S3 S5  S6  S8 === 40+42+65+30=177(一个商店最多购买同类商品一个)

 

[问题解决]

 

不按照清单数序-得出最省钱的最优解:

Step1:利用一个数组Store[8] ,存放商店的下标,1...8,,然后根据这样的排序比较规则对该数组的数组下标进行排序

(1)按照商品编号小的在前,大的在后

(2)同样的商品编号,价格小的在前,价格大的在后

然后对购物清单的各物品的商品编号进行进行排序,小的在前,大的在后

Step2:然后然后同时遍历排序后的 “购物清单数组” 和 “Store数组”,查看是否当前需要购买的商品即使该Store[i]商店出售的商品,是则输出该商店名称,并累加该商品价格。

 

 

按照清单顺序-按清单顺序最省的解答:

在找到一种可能的情况下,抛开找到的第一个匹配的商店,如果在该商店后续的商店中还存在匹配的情况,且花费更小,则得出较省的解答,如果后续商店中不存在匹配的情况,则后续的后续不可能再出现匹配的情况,直接退出匹配,当前得出的花费最省的情况即为解答。


[程序如下]

 

 

/* * main.cpp * * Created on: 2009-7-4 * Author: NeeSky */ #define MAXSIZE 100 #include <iostream> using namespace std; int GoodsID[MAXSIZE]; /*Goods ID of Store i*/ int GoodsPrice[MAXSIZE]; /*Goods Price*/ int OrderList[MAXSIZE]; /*Order-List for Goods */ /*** * Initialize the Problem and Global Variables and Output the Original Problem */ void InitPurchaseProblem(const int goodsID[], const int goodsPrice[], const int numStore, int orderList[], const int numNeed ) { for (int i = 0; i < numStore; ++i) { GoodsID[i] = goodsID[i]; GoodsPrice[i] = goodsPrice[i]; if (i < numNeed)OrderList[i] = orderList[i]; } for (int i = 0; i < numStore; ++i)cout << "S[" << i + 1 << "] ";cout << endl; for (int i = 0; i < numStore; ++i)cout << GoodsID[i] << " ";cout << endl; for (int i = 0; i < numStore; ++i)cout << GoodsPrice[i] << " ";cout << endl << endl; cout << "Order List : "; for (int i = 0; i < numNeed; ++i)cout << OrderList[i] << " ";cout << endl << endl; return; } /*** * Be used to output the result of purchase plan */ void outputPlan_forPurchase(int StorePurchased[], int numNeed ) { int SumPrice = 0; for (int j = 0; j < numNeed; j++) { if (StorePurchased[j] != -1) { if (j != 0) cout << " + "; SumPrice = SumPrice + GoodsPrice[StorePurchased[j]]; cout << "S[" << StorePurchased[j] + 1 << "]"; } else break; } cout << " = " << SumPrice << endl; return; } /*** * [ Important ] The Compare Principare */ int StoreCompare(const void* arg1, const void* arg2 ) { int* storeA = (int*) arg1; int *storeB = (int*) arg2; if (GoodsID[*storeA] > GoodsID[*storeB]) return 1; if (GoodsID[*storeA] < GoodsID[*storeB]) return -1; if (GoodsID[*storeA] == GoodsID[*storeB] && GoodsPrice[*storeA] > GoodsPrice[*storeB]) return 1; if (GoodsID[*storeA] == GoodsID[*storeB] && GoodsPrice[*storeA] == GoodsPrice[*storeB]) return 0; return -1; } /*** * Make the Purchase Plan */ void MakePlan_forPurchase(int numStore, int OrderList[], int numNeed, bool asOrderList ) { int StorePurchased[numNeed];//Store ID for Purchased for (int i = 0; i < numNeed; ++i)StorePurchased[i] = -1; //Initialize the Purchased Store ID to be -1 int StoresID[numStore];//Store ID for (int i = 0; i < numStore; ++i)StoresID[i] = i;//Initialize Store ID if (asOrderList == false) /********Greed Algorithm***************/ { std::sort(OrderList, OrderList + numNeed);//Make it be order as GoodsID std::qsort(StoresID, numStore, sizeof(int), StoreCompare);//Make it be order as "StoreCompare" Function* for (int i = 0 , j = 0; i < numStore && j < numNeed; ++i)//Start Purchase Goods if (GoodsID[StoresID[i]] == OrderList[j]) StorePurchased[j++] = StoresID[i]; std::sort(StorePurchased, StorePurchased + numNeed); } else /*****************Dynamic Plan******************/ { int MinMoney=0; for(int i=0; i<numStore; ) { int StorePurchasedNow[numNeed]; int MinMoneyNow=0;int k=0; for(int j= i; j < numStore && k<numNeed; ++j) { if(GoodsID[j]==OrderList[k]) { StorePurchasedNow[k++]= j; MinMoneyNow+=GoodsPrice[j]; } } if(k==numNeed&& (MinMoneyNow < MinMoney || MinMoney==0)) { MinMoney = MinMoneyNow; for(int t=0; t<numNeed; ++t) StorePurchased[t] = StorePurchasedNow[t]; i=StorePurchased[0]+1; //The Next Possible }else break; } } outputPlan_forPurchase(StorePurchased, numNeed); return; } int main() { const int numStore = 9; const int goodsID[numStore] = { 2, 5, 2, 1, 2, 2, 5, 5,1 }; //Goods ID of Store i const int goodsPrice[numStore] = { 30, 10, 25, 5, 20, 40, 15, 30, 10 };//Goods Price // const int numStore = 8; // const int goodsID[numStore] = { 2, 3, 2, 5, 2, 5, 4, 1 }; //Goods ID of Store i // const int goodsPrice[numStore] = { 50, 80, 40, 60, 42, 65, 100, 30 };//Goods Price const int numNeed = 4; int orderList[numNeed] = { 2, 2, 5, 1 }; InitPurchaseProblem(goodsID, goodsPrice, numStore, orderList, numNeed);// Initilize the Array cout<<"Dynamic Plan for purchase as Order List Sequency: "<<endl; MakePlan_forPurchase(numStore, OrderList, 4, true); cout<<endl; cout<<"Greed Algorithm for purchase [not]as Order List Sequency: "<<endl; MakePlan_forPurchase(numStore, OrderList, 4, false); return 0; }

 

 

[输出]:

 

S[1]     S[2]     S[3]     S[4]     S[5]     S[6]     S[7]     S[8]     
2        3        2        5        2        5        4        1        
50       80       40       60       42       65       100       30       

Order List   :   2     2     5     1     

Dynamic Plan for purchase as Order List Sequency:
S[3] + S[5] + S[6] + S[8] = 177

Greed Algorithm for purchase [not]as Order List Sequency:
S[3] + S[4] + S[5] + S[8] = 172

 

 

 

 

S[1]     S[2]     S[3]     S[4]     S[5]     S[6]     S[7]     S[8]     S[9]    
2        5        2        1        2        2        5        5        1       
30       10       25       5       20       40       15       30       10      

Order List   :   2     2     5     1    

Dynamic Plan for purchase as Order List Sequency:
S[3] + S[5] + S[7] + S[9] = 70

Greed Algorithm for purchase [not]as Order List Sequency:
S[2] + S[3] + S[4] + S[5] = 60

你可能感兴趣的:(Algorithm,算法,list,function,output,variables)