牛客算法周周练4 - 装备合成(三分、线性规划、贪心)

牛客算法周周练4 - 装备合成(三分、线性规划、贪心)

链接:https://ac.nowcoder.com/acm/contest/5505/E
来源:牛客网

时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 262144K,其他语言524288K
64bit IO Format: %lld

题目描述

牛牛有x件材料a和y件材料b,用2件材料a和3件材料b可以合成一件装备,用4件材料a和1件材料b也可以合成一件装备。牛牛想要最大化合成的装备的数量,于是牛牛找来了你帮忙。

输入描述:

输入包含t组数据
第一行一个整数t
接下来t行每行两个整数x,y

输出描述:

每组数据输出一行一个整数表示答案。

示例1

输入

5
4 8
7 6
8 10
100 4555
45465 24124

输出

2
2
3
50
13917

备注:

1<=t<=10000
1<=x,y<=1e9

 

 

假设方案一做了m件装备,方案二做了n件装备,我们遍历m来求n,n=min((x-2m)/4, y-3m),三分m,求n+m的最大值

由于三分时返回的m+n是整数,注意下面的情况时check(mid1)==check(mid2)&&check(mid1)<check(R) ,L=mid1+1,而不是R=mid2-1

 

 

 

 

 1 #include <bits/stdc++.h>
 2 typedef long long LL;
 3 #define pb push_back
 4 const int INF = 0x3f3f3f3f;
 5 const double eps = 1e-8;
 6 const int mod = 1e9+7;
 7 const int maxn = 1e5+10;
 8 using namespace std;
 9 
10 int x, y;
11 int check(int m)
12 {
13     return m+min((x-2*m)/4, y-3*m);
14 }
15 
16 int main()
17 {
18     #ifdef DEBUG
19     freopen("sample.txt","r",stdin); //freopen("data.out", "w", stdout);
20     #endif
21     
22     int T;
23     scanf("%d",&T);
24     while(T--)
25     {
26         scanf("%d %d",&x,&y);
27         int L=0, R = min(x/2, y/3);
28         int ans = 0;
29         while(L<=R)
30         {
31             int mid1 = L+(R-L)/3, mid2 = R-(R-L)/3;
32             int res1 = check(mid1), res2 = check(mid2);
33             ans = max(res1, res2);
34             if(res1<res2||(res1==res2&&res1<check(R))) L = mid1+1;
35             else R = mid2-1;
36         }
37         printf("%d\n", ans);
38     }
39     
40     return 0;
41 }

 

 

 

数学规划,高考的知识点,应该都不(wang)难(le)吧。。

具体的解法去看大佬的吧:https://blog.nowcoder.net/n/50e8388a544e429bb6deb9f876f715d5

 

 

 

 

看到还有大佬用贪心做的,妙啊,也写一下:

1、当x特别多时(x>4y),尽量用方案二,ans = y

2、当y特别多时(x/2 < y/3),尽量用方案一(方案二消耗一个y要消耗4个x),ans = x/2

3、两者没有明显差距时,我们根据两个式子 2x+3y和4x+y,可以看出合成一件装备必使用5个材料,同时最后总共消耗的x必是偶数,ans = (x+y)/5,如果s为奇数并且(x+y)%5==0,ans-1(除去x多3,y多2的情况)

 

 1 #include <bits/stdc++.h>
 2 typedef long long LL;
 3 #define pb push_back
 4 const int INF = 0x3f3f3f3f;
 5 const double eps = 1e-8;
 6 const int mod = 1e9+7;
 7 const int maxn = 1e5+10;
 8 using namespace std;
 9 
10 int main()
11 {
12     #ifdef DEBUG
13     freopen("sample.txt","r",stdin); //freopen("data.out", "w", stdout);
14     #endif
15     
16     int T;
17     scanf("%d",&T);
18     while(T--)
19     {
20         LL x, y; //记得开LL
21         scanf("%lld %lld",&x,&y);
22         LL ans = 0;
23         if(x > 4*y) ans = y; //x特别多
24         else if(x*3 < y*2) ans = x/2; //y特别多即x/2 < y/3
25         else
26         {
27             ans = (x+y)/5;
28             if(x&1&&(x+y)%5==0) ans--;
29         }
30         printf("%lld\n", ans);
31     }
32     
33     return 0;
34 }

 

 

 

 

 

 

 

-

posted @ 2020-05-03 00:28  jiamian22  阅读(517)  评论(0编辑  收藏  举报