https://www.luogu.com.cn/problem/CF2075D
有一个想法,不知道对不对(虽然没调好) 就是这道题说除以2k,每一个k只能使用一次。那我们可不可以将x和y转化为二进制,然后从高位至低位比较两者什么时候有差异,将不同的位数记为cnt1和cnt2,由于想要操作最小,然后将这个转化为两个背包问题来解决?
但是由于自己太菜了,不知道这种对不对,来问问大佬们
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int INF = 1e18;
int dp[605][605];
void work () {
int x, y;
cin >> x >> y;
if(x == y) {
cout << 0 << endl;
return ;
}
vector<int> tmp1, tmp2, a, b;
while (x) {
tmp1.push_back(x % 2);
x /= 2;
}
while (y) {
tmp2.push_back(y % 2);
y /= 2;
}
for (int i = tmp1.size() - 1; i >= 0; i --) {
a.push_back(tmp1[i]);
}
for (int i = tmp2.size() - 1; i >= 0; i --) {
b.push_back(tmp2[i]);
}
int sum1 = 0, sum2 = 0;
for (int i = 0; i < min(a.size(), b.size()); i ++) {
if (a[i] != b[i]) {
sum1 = a.size() - i;
sum2 = b.size() - i;
break;
}
}
if (a.size() == 0) {
cout << (1LL << b.size()) << endl;
return ;
}
if (b.size() == 0) {
cout << (1LL << a.size()) << endl;
return ;
}
for (int i = 0; i <= 66; i ++) {
for (int j = 0; j <= 66; j ++) {
dp[i][j] = INF;
}
}
dp[0][0] = 0;
for (int k = 1; k <= max(sum1, sum2); k++) {
for (int i = sum1; i >= 0; i --) {
for (int j = sum2; j >= 0; j --) {
if (dp[i][j] == INF) continue;
if (i + k <= sum1)
dp[i + k][j] = min(dp[i + k][j], dp[i][j] + (1LL << k));
if (j + k <= sum2)
dp[i][j + k] = min(dp[i][j + k], dp[i][j] + (1LL << k));
}
}
}
cout << dp[sum1][sum2] << endl;
}
signed main () {
int t;
cin >> t;
while (t --) {
work();
}
return 0;
}
// 0 0
// 2 2
// 2 2
// 4 4
// 0 0
// 4 4
// 4 4
// 2 0
// 2 0
// 4 4
// 6 8
// 2 0
// 0 0
// 2 0
// 6 8
// 6 8
// 4 0
// 12 1000000000000000000
// 12 1000000000000000000
这是我写了一部分的代码,下面的左边是正确输出,右边是我的输出,看这么大差别我感觉这个思路可能不太对……