HDOJ 4508 湫湫系列故事——减肥记I (完全背包带优化)

完全背包的模版题..

加了一个小优化  n^2的写法 O(V+N)在本题中复杂度较高 不采纳

完全背包问题有一个很简单有效的优化,是这样的:若两件物品i、j满足c[i]<=c[j]且w[i]>=w[j],则将物品j去掉,不用考虑。这个优化的正确性显然:任何情况下都可将价值小费用高得j换成物美价廉的i,得到至少不会更差的方案。对于 随机生成的数据,这个方法往往会大大减少物品的件数,从而加快速度。然而这个并不能改善最坏情况的复杂度,因为有可能特别设计的数据可以一件物品也去不掉。

这个优化可以简单的O(N^2)地实现,一般都可以承受。另外,针对背包问题而言,比较不错的一种方法是:首先将费用大于V的物品去掉,然后使用类似计数排序的做法,计算出费用相同的物品中价值最高的是哪个,可以O(V+N)地完成这个优化。

上代码了  优化后跑的蛮快的 

 1 #include <stdio.h>
 2 #include <iostream>
 3 #include <algorithm>
 4 #include <string.h>
 5 #include <math.h>
 6 #include <map>
 7 #include <limits.h>
 8 using namespace std;
 9 const long long MOD = 1e9+7;
10 typedef long long ll;
11 int c[110],w[110];
12 int f[100001];
13 bool vis[110];
14 
15 int main()
16 {
17     int n,m;
18     while(scanf("%d",&n)!=EOF)
19     {
20         memset(f,0,sizeof(f));
21         memset(vis,false,sizeof(vis));
22         for(int i=0;i<n;i++)
23         {
24             scanf("%d%d",&w[i],&c[i]);
25         }
26         scanf("%d",&m);
27         /*
28          n^2 优化
29         */
30         
31         for(int x=0;x<n;x++)
32         {
33             for(int y=x+1;y<n&&vis[x]==false;y++)
34             {
35                 if(c[x]<=c[y]&&w[x]>=w[y])
36                 {
37                     vis[y] = true;
38                 }
39                 else{
40                     if(c[y]<c[x]&&w[y]>w[x])
41                     {
42                         vis[x] = true;
43                     }
44                 }
45             }
46         }
47         for(int i=0;i<n;i++)
48         {
49             if(vis[i]) continue;
50             for(int j=c[i];j<=m;j++)
51             {
52                 f[j] = max(f[j],f[j-c[i]]+w[i]);
53             }
54             
55         }
56         printf("%d\n",f[m]);
57     }
58     return 0;
59 }
AC代码

 

posted @ 2016-10-28 11:46  zxMrlc  阅读(199)  评论(0编辑  收藏  举报