贪心策略:
数据(v1, v2),按 v2 - v1 的差值从大到小进行排序
分析:
例(1):
v = 10 2件物品:a(2, 5) b(6, 8)
-----如果先进a,再进b:
进a:v = 10 --> v >= 5 (成立) --> v -= 2 --> v = 8
进b:v = 8 --> v >= 8 (成立) --> v -= 6 --> v = 2 物品全部进入 输出Yes
-----如果先进b,再进a:
进b:v = 10 --> v >= 8 (成立) --> v -= 6 --> v = 4
进a:v = 4 --> v >= 5 (不成立) 物品未全部进入 输出No
例(2):
v = 13 2件物品:a(1, 3) b(9, 13)
-----如果先进a,再进b:
进a:v = 13 --> v >= 3 (成立) --> v -= 1 --> v = 12
进b:v = 12 --> v >= 13 (不成立) 物品未全部进入 输出No
-----如果先进b,再进a:
进b:v = 13 --> v >= 13 (成立) --> v -= 9 --> v = 4
进a:v = 4 --> v >= 3 (成立) --> v -= 1 --> v = 3 物品全部进入 输出Yes
总结:
两件物品时:a(x1, y1) b(x2, y2),此时,如果V的最小值为:min( max(y1, x1 + y2), max(y2, x2 + y1) ),max(y1, x1 + y2)即先进a,后进b,max(y2, x2 + y1)即先进b,后进a,得出两种进入方式的需要的最小容量值
当a(2, 5) b(6, 8),a差值3,b差值2 ==> min( x1 + y2 , x2 + y1) ==> x1 + y2 < x2 + y1 ==> y2 - x2 < y1 - x1 ==> 当a的差值大于b的差值时,此时有最小的容量v,所以先进a,后进b,即按物品差值从大到小排序
当a(1, 3) b(9, 13),a差值2,b差值4 ==> min( x1 + y2 , y2) ==> x1 + y2 > y2 ==> 因为y2 > x2 + y1,所以x1 + y2 > x2 + y1 ==> y2 - x2 > y1 - x1 ==> 当b的差值大于a的差值时,此时有最小容量v,所以先进b后进a,即按照物品差值从大到小排序
额外测试数据:
Input:
3
11 2
4 5
6 8
10 2
2 5
6 8
13 2
1 3
9 13
Output:
Yes
Yes
Yes
数据(x, y),刚开始以为贪心策略是以 y 值大小进行从大到小排序,问题考虑不周到......
1 #include <cstdio> 2 #include <cstring> 3 #include <iostream> 4 #include <algorithm> 5 using namespace std; 6 7 #define MAX 1010 8 9 struct Node 10 { 11 int a, b; 12 }node[MAX]; 13 14 bool cmp(Node x, Node y) 15 { 16 return x.b - x.a > y.b - y.a; 17 } 18 19 int main(void) 20 { 21 int t; 22 scanf("%d", &t); 23 while (t--) 24 { 25 memset(node, 0, sizeof(node)); 26 int v, n; 27 scanf("%d%d", &v, &n); 28 for (int i = 0; i < n; i++) 29 { 30 scanf("%d%d", &node[i].a, &node[i].b); 31 } 32 sort(node, node + n, cmp); 33 int flag = 0; 34 for (int i = 0; i < n; i++) 35 { 36 if (v >= node[i].b) 37 { 38 v -= node[i].a; 39 } 40 else 41 { 42 flag = 1; 43 break; 44 } 45 } 46 if (flag) 47 { 48 printf("No\n"); 49 } 50 else 51 { 52 printf("Yes\n"); 53 } 54 } 55 return 0; 56 57 }
HDU Crixalis's Equipment(贪心)
原文地址:https://www.cnblogs.com/changeFeng/p/9329276.html