【三分/贪心】装备合成
题目
思路
设方案一A次,方案二B次
2
A
+
4
B
<
=
X
2A+4B<=X
2A+4B<=X
3
A
+
B
<
=
Y
3A+B<=Y
3A+B<=Y
求
A
+
B
A+B
A+B最大值
高中线性规划,对于二元式子,我们先消元。
B
<
=
(
X
−
2
A
)
/
4
B<=(X-2A)/4
B<=(X−2A)/4
B
<
=
Y
−
3
A
B<=Y-3A
B<=Y−3A
所以
B
<
=
m
i
n
(
(
X
−
2
A
)
/
4
,
Y
−
3
A
)
B<=min((X-2A)/4,Y-3A)
B<=min((X−2A)/4,Y−3A)
目标为:
f
(
x
)
=
A
+
m
i
n
(
(
X
−
2
A
)
/
4
,
Y
−
3
A
)
f(x)=A+min((X-2A)/4,Y-3A)
f(x)=A+min((X−2A)/4,Y−3A)
如果对A进行枚举,那必然超时,接下来观察目标函数的性质
(
X
−
2
A
)
/
4
<
Y
−
3
A
时
,
即
X
<
4
Y
−
10
A
…
…
单
调
上
升
(X-2A)/4<Y-3A时,即X<4Y-10A……单调上升
(X−2A)/4<Y−3A时,即X<4Y−10A……单调上升
f
(
x
)
=
A
+
(
X
−
2
A
)
/
4
…
…
①
单
调
上
升
f(x)=A+(X-2A)/4……①单调上升
f(x)=A+(X−2A)/4……①单调上升
X
>
=
4
Y
−
10
A
时
X>=4Y-10A时
X>=4Y−10A时
f
(
x
)
=
Y
−
2
A
…
…
②
单
调
下
降
f(x)=Y-2A……②单调下降
f(x)=Y−2A……②单调下降
显然的,先①后②,构成的函数时是个凸函数
对于凸函数,我们采用三分法来解决
代码
// Problem: 装备合成
// Contest: NowCoder
// URL: https://ac.nowcoder.com/acm/problem/200211
// Memory Limit: 524288 MB
// Time Limit: 2000 ms
// FishingRod
#include<bits/stdc++.h>
using namespace std;
#define endl "\n"
typedef long long LL;
typedef pair<int,int> PII;
#define MULINPUT
/*DATA & KEY
t 1 1e4
x 1 1e9
y 1 1e9
*/
int T;
LL x,y;
LL check(LL mid)
{
return mid+min((x-2*mid)/4,y-3*mid);
}
void solve()
{
//NEW DATA CLEAN
//NOTE!!!
cin>>x>>y;
LL l=0,r=min(x/2,y/3);
while(l<r)
{
LL lmid=l+(r-l)/3;
LL rmid=r-(r-l)/3;
if(check(lmid)>check(rmid))r=rmid-1;
else l=lmid+1;
}
cout<<check(l)<<endl;
}
int main()
{
#ifdef MULINPUT
scanf("%d",&T);
for(int i=1;i<=T;i++)solve();
#else
solve();
#endif
return 0;
}
反思
多种选择可以设每个选择进行多少次。
求最值:二分,三分,DP
如何把一个问题转为三分/三分?
首先对于多元的式子进行校园,先看答案,然后看限制。
然后想想暴力的,转为一元问题后暴力枚举
此时可以打表观察规律,或者像这题一样讨论单调性