3B.Lorry(贪心)

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了3B.Lorry(贪心)相关的知识,希望对你有一定的参考价值。

这道题是属于贪心题。

题目链接:http://codeforces.com/problemset/problem/3/B

题目大意是:

  有两种船:一种是皮划艇,另一种是双人船。皮划艇占地1平米,双人船占地2平米。现在有一辆大货车,要将一定数量皮划艇和双人船运到港口。现在每个皮划艇和双人船的承载能力都不相同。问怎样放置皮划艇和双人船,能使总的承载能力最大,且货车的剩余空间最小,最好没有剩余空间。

  这道题采用贪心算法,按照承载能力进行降序排列。因为我们要使总的承载能力最大,则优先选择的就是承载能力大的船。因为双人船占地2平米,则每平米承载能力就要除以2,然后按照每平米的承载能力来排序。

  然后就是要注意一点,当放到最后时,可能会有1平米的空间剩余。在这时,将进行以下步骤:

  1.将后面1平米的皮划艇放上来;

  2.将最后放到货车上的皮划艇去掉,然后放后面的双人船;

  3.比较方式1和方式2,看哪种方式的承载能力更高,然后决定选择那种方式。

 

  接着就是打印放置船的序列号。

 

代码如下:

 1 #include <iostream>
 2 #include <algorithm>
 3 using namespace std;
 4 
 5 
 6 struct vehicle{
 7     int order;              //保存序列号
 8     int type;               //保存船的类型(占地)
 9     double weight;          //承载能力
10 }veh[100001];
11 
12 bool camp(const struct vehicle &a, const struct vehicle &b){     //按承载能力降序排序
13     return a.weight > b.weight;
14 }
15 
16 int main(){
17     int n, v;
18     while(cin>>n>>v){
19         for (int i = 1; i <= n; ++i){
20             cin>>veh[i].type>>veh[i].weight;
21             veh[i].order = i;
22             if (veh[i].type == 2){
23                 veh[i].weight = 1.0 * veh[i].weight / 2;       //平均到每平米
24             }
25         }
26 
27         sort(veh + 1, veh + n + 1, camp);
28 
29         int sum = 0, capacity = 0;
30         int flag = 0, k = 0;
31         for (int i = 1; i <= n; ++i){
32             if (capacity + veh[i].type <= v){     //不断枚举
33                 if (veh[i].type == 2)
34                     sum += 2 * veh[i].weight;
35                 else{
36                     k = i;
37                     sum += veh[i].weight;
38                 }
39                 capacity += veh[i].type;
40                 flag = i;
41             } else{
42                 break;
43             }
44         }
45 
46         int temp1 = 0, temp2 = 0;
47         int key1 = 0, key2 = 0, k3 = 0; 
48         if (capacity == v - 1){                             //当剩余1平米时
49             for (int i = flag + 1; i <= n; ++i){
50                 if (!temp1 && veh[i].type == 2){            //方式2
51                     temp1 = veh[i].weight * 2;
52                     key1 = i;
53                 } else if (!temp2 && veh[i].type == 1){     //方式1
54                     temp2 = veh[i].weight;
55                     key2 = i;  
56                 }
57                 if (temp1 && temp2)
58                     break;
59             }
60 
61             /* 比较两种方式哪种的承载能力更高  */
62             if (k != 0){
63                 if (temp2 + veh[k].weight >= temp1){
64                     sum += temp2;
65                     k3 = key2;
66                 }
67                 else {
68                     sum = sum - veh[k].weight + temp1;
69                     k3 = key1;
70                 } 
71             } else {
72                     sum += temp2;
73                     k3 = key2;
74             }
75         }
76 
77         /* 打印结果 */
78         cout<<sum<<endl;
79         if (sum != 0){
80             cout<<veh[1].order;
81             for (int i = 2; i <= flag; ++i){
82                 if (capacity == v - 1 && k3 == key1 && key1 != 0 && k != 0){
83                     if (i != k){
84                         cout<<" "<<veh[i].order;
85                     }
86                 } else 
87                 {
88                     cout<<" "<<veh[i].order;
89                 }
90             }
91             if (k3 != 0)
92                 cout<<" "<<veh[k3].order;
93         }    
94         cout<<endl;
95     }
96 }

 

以上是关于3B.Lorry(贪心)的主要内容,如果未能解决你的问题,请参考以下文章

CF3B Lorry

贪心算法:划分字母区间

763. 划分字母区间-贪心算法

贪心热门问题8:划分字母区间

Contig|scaffold|N50|L50|NG50|贪心算法|de bruiji graph|

CodeForces 1005D Polycarp and Div 3(思维贪心dp)