Shopping Offers USACO 3.3 (dp完全背包)

这题能做对我都不信,开始想了好久感觉确实类似完全背包,dp表不好定义,完全背包一维数组就完了,这里最多要买5种商品

于是去看了眼题解,就看到dp两字和一个5维数组....

我去,真有5维数组这种东西...不过一想确实可以啊,虽然麻烦点。不过一样是完全背包的思想。

dp[5][5][5][5][5],有点区别是完全背包原题是求最大价值,

状态方程是dp[n]=max(dp[n],dp[n-weight(m)]+value(m));且初始dp[1]到dp[n]为0

这里要求最小,就要反过来一下

初始时dp[a][b][c][d][e] (a-e分别代表对应位置的商品的个数)要=a*price(1)+b*price(2)... ,就是单独买的价格(此时肯定是价格最高的)

然后状态方程是

dp[a][b][c][d][e]=min(dp[a][b][c][d][e],dp[a-优惠对应位置商品的数量][...]+优惠的价格)

当然前提是 优惠的商品数量一定小于等于对应的a-e

最后结果存储在dp[][][][][] 要买的数量里...

第二次就过了哈哈哈、

  1 /*
  2 
  3 ID: hubiao cave
  4 
  5 PROG: shopping
  6 
  7 LANG: C++
  8 
  9 */
 10 
 11 
 12 
 13 
 14 #include<iostream>
 15 #include<fstream>
 16 #include<utility>
 17 #include<list>
 18 #include<algorithm>
 19 #include<cstring>
 20 
 21 using namespace std;
 22 
 23 
 24 struct offer
 25 {
 26     pair<int,int> kind_and_number[5];
 27     int price;
 28     int goods_number;
 29 };
 30 
 31 list<offer*> g_offer_list;
 32 
 33 int g_customers[1000][2];
 34 int g_offer_number;
 35 int g_buy_number;
 36 pair<int,int> g_kind_number[5];
 37 
 38 int dp[6][6][6][6][6]={0};
 39 
 40 int main()
 41 
 42 {
 43 
 44     ifstream fin("shopping.in");
 45     ofstream fout("shopping.out");
 46     fin>>g_offer_number;
 47     for(int i=0;i<g_offer_number;i++)
 48     {
 49         offer*po=new offer;
 50         memset(po,0,sizeof(offer));
 51         fin>>po->goods_number;
 52         for(int j=0;j<po->goods_number;j++)
 53             fin>>po->kind_and_number[j].first>>po->kind_and_number[j].second;
 54         fin>>po->price;
 55         g_offer_list.push_back(po);
 56     }
 57     
 58     fin>>g_buy_number;
 59     for(int i=0;i<g_buy_number;i++)
 60     {
 61         int temp;
 62         fin>>temp;
 63         fin>>g_customers[temp][0]>>g_customers[temp][1];
 64         g_kind_number[i].first=temp;
 65         g_kind_number[i].second=g_customers[temp][0];
 66     }
 67     
 68     for(list<offer*>::iterator it=g_offer_list.begin();it!=g_offer_list.end();)
 69     {
 70         bool flag=false;
 71         for(int i=0;i<(*it)->goods_number;i++)
 72         {
 73             int kind=(*it)->kind_and_number[i].first;
 74             int number=(*it)->kind_and_number[i].second;
 75             if(!g_customers[kind][0]||g_customers[kind][0]<number)
 76             {
 77                 it=g_offer_list.erase(it);
 78                 flag=true;
 79                 continue;
 80             }
 81         }
 82         if(!flag)
 83         {
 84             it++;
 85             //sort(it->kind_and_number[0],it->kind_and_number[it->goods_number]);
 86         }
 87             
 88     }
 89 
 90 
 91     sort(&g_kind_number[0],&g_kind_number[g_buy_number]);
 92     for(list<offer*>::iterator it=g_offer_list.begin();it!=g_offer_list.end();it++)
 93     {
 94 
 95         for(int i=0;i<5;i++)
 96         {
 97             for(int j=0;j<5;j++)
 98             {
 99                 if((*it)->kind_and_number[j].first==g_kind_number[i].first)
100                 {
101                     if(i==j)
102                         break;
103                     else
104                     {
105                         swap((*it)->kind_and_number[i],(*it)->kind_and_number[j]);
106                         break;
107                     }
108                 }
109             }
110         }
111     }
112 
113     for(int a=0;a<=g_kind_number[0].second;a++)
114             for(int b=0;b<=g_kind_number[1].second;b++)
115                 for(int c=0;c<=g_kind_number[2].second;c++)
116                     for(int d=0;d<=g_kind_number[3].second;d++)
117                         for(int e=0;e<=g_kind_number[4].second;e++)
118                             {
119                                 pair<int,int>*p=g_kind_number;
120                                 dp[a][b][c][d][e]=a*g_customers[p[0].first][1]+b*g_customers[p[1].first][1]+c*g_customers[p[2].first][1]+d*g_customers[p[3].first][1]+e*g_customers[p[4].first][1];
121                             }
122 
123     for(list<offer*>::iterator it=g_offer_list.begin();it!=g_offer_list.end();it++)
124     {
125 
126         for(int a=0;a<=g_kind_number[0].second;a++)
127             for(int b=0;b<=g_kind_number[1].second;b++)
128                 for(int c=0;c<=g_kind_number[2].second;c++)
129                     for(int d=0;d<=g_kind_number[3].second;d++)
130                         for(int e=0;e<=g_kind_number[4].second;e++)
131                             {
132                                 pair<int,int>* p=(*it)->kind_and_number;
133                                 int price=(*it)->price;
134                                 if(p[0].second<=a&&p[1].second<=b&&p[2].second<=c&&p[3].second<=d&&p[4].second<=e)
135                                 {
136                                     dp[a][b][c][d][e]=min(dp[a][b][c][d][e],dp[a-p[0].second][b-p[1].second][c-p[2].second][d-p[3].second][e-p[4].second]+price);
137                                 }
138                             }
139     }
140 
141     fout<<dp[g_kind_number[0].second][g_kind_number[1].second][g_kind_number[2].second][g_kind_number[3].second][g_kind_number[4].second]<<endl;
142 
143     return 0;
144 
145 
146 }
原文地址:https://www.cnblogs.com/cavehubiao/p/3366128.html