P2732 [USACO3.3]商店购物 Shopping Offers

原题链接

考察:背包dp

思路:

        做之前看成01背包,然后答案一直不对,醉了.

        实际是完全背包,因为需要的东西不超过5类,且不超过5个,所以可以用5维数组.5类物品的数目都是体积.

        需要将编号离散化,这里用的是map映射.

        但是注意的是我的本地IDE 在mp[x] = mp.size()是从1开始,但是洛谷的IDE是从0开始.可能不同编辑器不一样,还是老老实实设置一个变量较好.

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <map>
 5 #include <vector>
 6 using namespace std;
 7 const int N = 105,M = 6,INF = 0x3f3f3f3f;
 8 typedef pair<int,int> PII;
 9 vector<PII> dis[N];
10 map<int,int> mp;
11 int s,n,price[N],f[M][M][M][M][M],cnt;
12 int need[M];
13 struct LIST{
14     int nums[6],pce;
15 }list[N+M];
16 int get(int x)
17 {
18     if(!mp.count(x)) mp[x] =mp.size();
19     return mp[x];
20 }
21 void init()
22 {
23     scanf("%d",&s);
24     for(int i=1;i<=s;i++)//折扣 
25     {
26         int m,c,k;
27         scanf("%d",&m);
28         for(int j=1;j<=m;j++)
29         {
30             scanf("%d%d",&c,&k);
31             dis[i].push_back({c,k});
32         }
33         scanf("%d",&price[i]);
34     }
35     scanf("%d",&n);
36     for(int i=1;i<=n;i++)//需求 
37     {
38         int c,k,p; scanf("%d%d%d",&c,&k,&p);
39         list[++cnt].nums[get(c)] = 1;
40         list[cnt].pce = p;
41         need[get(c)] = k;
42     }
43     cnt++;
44     for(int i=1;i<=s;i++,cnt++)
45         for(int j=0;j<dis[i].size();j++)
46         {
47             int x = get(dis[i][j].first),y = dis[i][j].second;
48             if(x>5) continue;
49             list[cnt].nums[x] = y;
50             list[cnt].pce = price[i];
51         }
52 }
53 void work()
54 {
55     memset(f,0x3f,sizeof f);
56     f[0][0][0][0][0] = 0;
57     for(int I=1;I<=cnt;I++)
58      for(int i=list[I].nums[1];i<=need[1];i++)
59        for(int j=list[I].nums[2];j<=need[2];j++)
60          for(int k=list[I].nums[3];k<=need[3];k++)
61           for(int p=list[I].nums[4];p<=need[4];p++)
62            for(int l=list[I].nums[5];l<=need[5];l++)
63            {
64                  int a = list[I].nums[1],b = list[I].nums[2];
65                  int c = list[I].nums[3],d = list[I].nums[4];
66                  int e = list[I].nums[5],g = f[i][j][k][p][l];
67                  if(f[i-a][j-b][k-c][p-d][l-e]>=INF) continue;
68                  f[i][j][k][p][l] = min(f[i-a][j-b][k-c][p-d][l-e]+list[I].pce,g);
69            }
70             
71 }
72 int main()
73 {
74     init();
75     work();
76     printf("%d\n",f[need[1]][need[2]][need[3]][need[4]][need[5]]);
77     return 0;
78 }

 

posted @ 2021-04-01 14:28  acmloser  阅读(126)  评论(0编辑  收藏  举报