首先我们必须知道,与运算会使得我们的数越来越小,所以我们为了保留最大价值,就直接只取一个就好了,但是如果存在一个很大的价值,但是容量大于 k ,能否通过& 运算使得容量变小呢,但是这种情况下价值会小于二者任意一个,所以不可能是最优解
好吧上面的思路是错的,因为可能我们所有的价值都大于k,这样我们就必须 & 运算
下面有一个思路就是枚举最大价值,如果我们当前有价值&最大价值还是最大价值,那么我们在尽可能的把体积弄小一点
#define _CRT_SECURE_NO_WARNINGS
#include<bits/stdc++.h>
using namespace std;
#define int long long
int n,k;
const int N = (int)2e3+5;
int v[N],w[N]; // v是价值,w是重量
int dp[N];
int solve(){
for(int i=2000;i;i--){
int temp = 0xffffffff;
for(int j=1;j<=n;j++){
if((v[j]&i)==i){
temp &= w[j]; // 使得我们的体积尽可能的小
}
if(temp!=0xffffffff&&temp<=k){
return i;
}
}
}
}
signed main(){
cin >> n >> k;
for(int i=1;i<=n;i++){
cin >> w[i] >> v[i];
}
// 我们只需要搞懂一点,按位与只可能越来越小
cout << solve();
return 0;
}
可以从高位开始, 用试填法, 逐位确定
#define _CRT_SECURE_NO_WARNINGS
#include<bits/stdc++.h>
using namespace std;
#define int long long
int n,k;
const int N = (int)2e5+5;
const int M = (int)1e9;
int v[N],w[N]; // v是价值,w是重量
int dp[N];
int solve(){
int ans = 0; // 贪心的思路,依次枚举高位
for(int i=30;i>=0;i--){
int temp = ans | (1<<i);
int t = (1<<30)-1; // 构造都是1的序列
for(int j=1;j<=n;j++){
if((v[j]&temp)==temp){
t &= w[j];
}
}
if(t<=k){
ans += (1<<i);
}
}
return ans;
}
signed main(){
cin >> n >> k;
for(int i=1;i<=n;i++){
cin >> w[i] >> v[i];
}
// 我们只需要搞懂一点,按位与只可能越来越小
cout << solve();
return 0;
}