链接: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
备注:
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)
![牛客算法周周练4 - 装备合成(三分、线性规划、贪心)_第1张图片](http://img.e-com-net.com/image/info8/0c28bbb2e9034fa6bfd4552307f146c3.jpg)
1 #include
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(res11;
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
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 }
-