码迷,mamicode.com
首页 > 其他好文 > 详细

codeforces - 148E 题解

时间:2017-08-20 16:52:39      阅读:116      评论:0      收藏:0      [点我收藏+]

标签:space   分组背包   scanf   end   color   题目   fonts   ems   log   

题目大意:一个公主有一个摆满瓷器的架子,她生气的时候就要打碎m个瓷器。这个架子有n层,每层的瓷器每次只能从最左边拿或者从最右边拿,问打碎的瓷器的最大价值。

题解:这是一个泛化物品+分组背包的DP,首先将每一层上拿出瓷器的方案作为一个物品,拿出瓷器的方案的代价是瓷器数量,价值是这一层上所有方案中最大的价值。

首先为了计算方案的时候可以快速计算,我们在读入的时候就计算出前缀和sum,然后在计算方案的时候,每一层上打碎的数量对应一个物品,然后枚举总数量分配到两侧打碎的价格,得到最大价值。最后使用分组背包解决。

分组背包常见代码:

K代表有K个组,V是背包最大容量,这里要注意在最里面要防止v-ci小于0,否则会出现未定义行为,导致计算错误

for k 1 to K
  for v V to 0
    for all item i in group k
      F[v]=max(F [v], F [v - Ci] + Wi);

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<algorithm>
 4 #include<cstring>
 5 #include<vector>
 6 using namespace std;
 7 struct datatype
 8 {
 9     int value;
10     int space;
11 };
12 vector<datatype> a[101];
13 int shelf[101][101];
14 int sum[101][101];
15 int amount[101];
16 int f[10001];
17 int main()
18 {
19     int n,m;
20     scanf("%d%d",&n,&m);
21     memset(sum,0,sizeof(sum));
22     for(int i=1;i<=n;i++)
23     {
24         int x;
25         scanf("%d",&x);
26         amount[i]=x;
27         for(int j=1;j<=x;j++)
28         {
29             scanf("%d",&shelf[i][j]);
30             sum[i][j]=sum[i][j-1]+shelf[i][j];
31         }
32     }
33     for(int i=1;i<=n;i++)
34     {
35         for(int k=1;k<=amount[i];k++)
36         {
37             datatype tmp;
38             tmp.space=k;
39             tmp.value=0;
40             for(int j=0;j<=k;j++)
41             {
42                 int tmp_v=0;
43                 tmp_v+=sum[i][j];
44                 tmp_v+=sum[i][amount[i]]-sum[i][amount[i]-(k-j)];
45                 tmp.value=max(tmp_v,tmp.value);
46             }
47             a[i].push_back(tmp);
48         }
49     }
50     memset(f,0,sizeof(f));
51     for(int i=1;i<=n;i++)
52     {
53         for(int j=m;j>=0;j--)
54         {
55             vector<datatype>::iterator it;
56             for(it=a[i].begin();it!=a[i].end();it++)
57             {
58                 if(j-(*it).space<0)
59                 {
60                     continue;
61                 }
62                 f[j]=max(f[j],f[j-(*it).space]+(*it).value);
63             }
64         }
65     }
66     printf("%d\n",f[m]);
67     return 0;
68 }

 

codeforces - 148E 题解

标签:space   分组背包   scanf   end   color   题目   fonts   ems   log   

原文地址:http://www.cnblogs.com/shao0099876/p/7400316.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!