完全背包

先列一些完全背包的题目:

洛谷 P1941 飞扬的小鸟

 

HDU 6007 Mr. Panda and Crystal

题意:有 \(n\) 个物品,\(m\) 块钱。每个物品价值为 \(v_i\),购买代价为 \(w_i\)。现在有 \(k\) 个规则,规则形如物品 \(x\) 可由 \(n_{i_1}\) 个物品 \(i_1\),\(n_{i_2}\) 个物品 \(i_2\),...,\(n_{i_l}\) 个物品 \(i_l\) 合成。问不超过 \(m\) 块钱能获得的最大价值。

Solution:

  先用dijkstra预处理出每个物品的最小代价,时间复杂度是 \(O(kn^2)\)。之后用完全背包,时间复杂度是 \(O(nm)\)。

 1 #include<bits/stdc++.h>
 2 #define rep(i,a,n) for(int i=a;i<=n;i++)
 3 #define per(i,a,n) for(int i=n;i>=a;i--)
 4 #define pb push_back
 5 #define mp make_pair
 6 #define FI first
 7 #define SE second
 8 #define maxn 200
 9 #define mod 1000000007
10 #define inf 0x3f3f3f3f
11 using namespace std;
12 typedef long long ll;
13 typedef pair<int,int> pii;
14 typedef vector<int> vi;
15 typedef double db;
16 
17 int dis[maxn+5],v[maxn+5];
18 
19 struct node
20 {
21     int v,dis;
22     node(){}
23     node(int a,int b):v(a),dis(b){}
24     bool operator <(const node &a) const {return dis>a.dis;}
25 };
26 priority_queue<node> q;
27 bool mark[maxn+5];
28 
29 struct E
30 {
31     int to;
32     vector<pii> edge;
33 }e[maxn+5];
34 
35 vi eid[maxn+5];
36 
37 int dp[10000+5];
38 
39 int main()
40 {
41     int CAS; scanf("%d",&CAS);
42     rep(cas,1,CAS)
43     {
44         int m,n,k; scanf("%d%d%d",&m,&n,&k);
45         rep(i,1,n)
46         {
47             int x; scanf("%d",&x);
48             if(x==1) scanf("%d%d",&dis[i],&v[i]),q.push(node(i,dis[i]));
49             else dis[i]=inf,scanf("%d",&v[i]);
50         }
51         rep(i,1,n) eid[i].clear();
52         rep(i,1,k)
53         {
54             scanf("%d",&e[i].to);
55             e[i].edge.clear();
56             int x; scanf("%d",&x);
57             while(x--)
58             {
59                 int from,num; scanf("%d%d",&from,&num);
60                 e[i].edge.pb(mp(from,num));
61                 eid[from].pb(i);
62             }
63         }
64         rep(i,1,n) mark[i]=0;
65         while(!q.empty())
66         {
67             int now=q.top().v;
68             q.pop();
69             if(mark[now]) continue;
70             mark[now]=1;
71             for(auto id: eid[now])
72             {
73                 ll d=0;
74                 int v=e[id].to;
75                 for(auto it: e[id].edge) d+=1ll*dis[it.FI]*it.SE;
76                 if(dis[v]>d)
77                 {
78                     dis[v]=d;
79                     q.push(node(v,d));
80                 }
81             }
82         }
83         rep(i,0,m) dp[i]=0;
84         rep(i,1,n) rep(j,1,m) if(j>=dis[i]) dp[j]=max(dp[j],dp[j-dis[i]]+v[i]);
85 
86         printf("Case #%d: %d\n",cas,dp[m]);
87     }
88     return 0;
89 }
View Code

 

posted @ 2018-12-19 18:35  YaoBIG  阅读(92)  评论(0)    收藏  举报