题解 P6746 【Operations】
囧仙
2020-08-08 20:09:02
## 题目大意
有两个非负整数 $a,b$ 。现有两种操作。
- $a\gets a-x,b\gets b-x$ ,其中 $x$ 为正整数。此操作花费非负整数 $c$ 。
- $a\gets a\times x,b\gets \left\lfloor\dfrac{b}{x}\right\rfloor$ ,或者 $b\gets b\times x,a\gets \left\lfloor\dfrac{a}{x}\right\rfloor$ , 其中 $x$ 为正整数。此操作花费非负整数 $d$ 。
询问将 $a,b$ 都变成 $0$ 所花费的最大权值。
## 题解
一道挺有意思的分类讨论题。
- 当 $a=b=0$ 时,显然答案为 $0$ 。
- 当其中一个为 $0$ 时,我们可以执行操作 $2$ , $x$ 取一个很大的值。此时另外一个非零的元素就能通过除法变成 $0$ 。
- 当两者都不为 $0$ 时,又存在三种情况。
- 当 $a=b$ 时 ,我们可以仅使用一次操作 $1$ 。
- 使用操作 $1$ 将更小的那个数减到 $0$ 。另外一个数就可以使用一次操作 $2$ 变成 $0$ 。
- 使用两次操作 $2$ 。先将某个数除成 $0$ ,再将另外一个数除成 $0$ 。
一个公式概括答案:
$$ans=\begin{cases}
0 & a=b=0 \cr
d & a\times b=0 \text{ 且 } a+b\neq 0 \cr
\min\{c,2\times d\} & a=b\neq 0 \cr
\min\{c+d,2\times d\} & \text{其他情况}
\end{cases}$$
## 参考代码
```cpp
#include<bits/stdc++.h>
#define up(l,r,i) for(int i=l;i<=r;i++)
#define dn(l,r,i) for(int i=l;i>=r;i--)
using namespace std;
typedef long long LL;
const int INF =2147483647;
int qread(){
int w=1,c,ret;
while((c=getchar())> '9'||c< '0') w=(c=='-'?-1:1); ret=c-'0';
while((c=getchar())>='0'&&c<='9') ret=ret*10+c-'0';
return ret*w;
}
int a,b,c,d,ans=INF;
int main(){
a=qread(),b=qread(),c=qread(),d=qread();
ans=min(ans,c+d);
if(a==b) ans=min(ans,c);
if(a==0||b==0){
ans=min(ans,d);
}
ans=min(ans,2*d);
if(a==0&&b==0) ans=0;
printf("%d\n",ans);
return 0;
}
```