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

HDU 5445 Food Problem(多重背包+二进制优化)

时间:2017-12-01 11:33:47      阅读:109      评论:0      收藏:0      [点我收藏+]

标签:std   turn   can   ios   eof   targe   题意   problem   ems   

http://acm.hdu.edu.cn/showproblem.php?pid=5445

题意:
现在你要为运动会提供食物,总共需要提供P能量的食物,现在有n种食物,每种食物能提供 t 能量,体积为 u ,并且最多能提供 v 的数量。运载食物的卡车有m种,每种能提供 x 的运输空间,运输花费为 y,最多可以雇佣 z 辆车。食物可以切割后运输。不需要整块一起运输,但只有一整块全部到达时才能提供能量。

现在需要计算出最少需要多少花费。

 

思路:

因为食物可以切割运输,那么食物的总体积肯定是越小越好,所以先用多重背包计算出提供P能量所需的最少食物体积,食物的能量最多能提供100,所以背包容量到P+100即可。

有了体积之后,接下来只需要计算运输这些体积的食物最少需要多少花费,再用一次多重背包即可。

需要使用二进制优化。

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 using namespace std;
 5 const int INF = 0x3f3f3f3f;
 6 
 7 int n,m,p,tot;
 8 int val[2005],cost[2005];
 9 int dp[50005];
10 
11 int solve1()
12 {
13     for(int i=0;i<=p+100;i++)  dp[i] = INF;
14     dp[0] = 0;
15     for(int i=0;i<tot;i++)
16         for(int j=p+100;j>=val[i];j--)
17         dp[j] = min(dp[j],dp[j-val[i]]+cost[i]);
18     int ans = INF;
19     for(int i=p;i<=p+100;i++)
20         ans = min(ans, dp[i]);
21     return ans;
22 }
23 
24 
25 int solve2(int v)
26 {
27     memset(dp,0,sizeof dp);
28     for(int i=0;i<tot;i++)
29         for(int j=50000;j>=cost[i];j--)
30         dp[j] = max(dp[j],dp[j-cost[i]]+val[i]);
31     for(int i=1;i<=50000;i++)
32         if(dp[i]>=v) return i;
33     return INF;
34 }
35 
36 int main()
37 {
38     //freopen("in.txt","r",stdin);
39     int T;
40     scanf("%d",&T);
41     while(T--)
42     {
43         scanf("%d%d%d",&n,&m,&p);
44         tot = 0;
45         for(int i=1;i<=n;i++)
46         {
47             int t,u,v;
48             scanf("%d%d%d",&t,&u,&v);
49             for(int k=1;v;k<<=1)
50             {
51                 int num = min(k,v);
52                 val[tot] = num*t;
53                 cost[tot++] = num*u;
54                 v -= num;
55             }
56         }
57         int v = solve1();
58         tot = 0;
59         for(int i=1;i<=m;i++)
60         {
61             int x,y,z;
62             scanf("%d%d%d",&x,&y,&z);
63             for(int k=1;z;k<<=1)
64             {
65                 int num = min(k,z);
66                 cost[tot] = num*y;
67                 val[tot++] = num*x;
68                 z -= num;
69             }
70         }
71         if(v==INF) {puts("TAT");continue;}
72         int ans = solve2(v);
73         if(ans==INF)  puts("TAT");
74         else printf("%d\n",ans);
75     }
76     return 0;
77 }

 

HDU 5445 Food Problem(多重背包+二进制优化)

标签:std   turn   can   ios   eof   targe   题意   problem   ems   

原文地址:http://www.cnblogs.com/zyb993963526/p/7940424.html

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