Equalization
题目大意
题目大意
给定两个非负整数 x 和 y,你可以执行任意次操作(包括零次):
- 选择一个正整数 k
- 将 x 或 y 除以 2^k(向下取整)
- 操作成本为 2^k
- 限制条件:同一个 k 值只能使用一次
目标:通过若干次操作,使得 x = y,求最小总成本。
代码
#include <bits/stdc++.h>
using namespace std;
using ll=long long;
const int B=60;
const ll inf=1e18;
void so(){
}int main(){
ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
array<array<ll,B>,B>dp;
for(int i=0;i<B;i++){
for(int j=0;j<B;j++){
dp[i][j]=inf;
}
}dp[0][0]=0;//都不除代价为0
for(int k=0;k<B;k++){
for(int i=B-1;i>=0;i--){
for(int j=B-1;j>=0;j--){
if(dp[i][j]==inf)continue;
if(i+k<B){
dp[i+k][j]=min(dp[i+k][j],dp[i][j]+(1ll<<k));
}if(j+k<B){
dp[i][j+k]=min(dp[i][j+k],dp[i][j]+(1ll<<k));
}
}//背包(倒着)保证只用一次
//保证每个状态只用了一次
}
}int t;cin>>t;
while(t--){
ll x,y;cin>>x>>y;
ll ans=inf;
for(ll i=0;i<B;i++){
for(ll j=0;j<B;j++){
if((x>>i)==(y>>j))ans=min(ans,dp[i][j]);
}
}
cout<<ans<<'\n';
}
}
思路
只用一次并且有代价要想到背包dp