小苯的01背包easy(枚举,位运算,思维推导)

2024-05-26 00:36

本文主要是介绍小苯的01背包easy(枚举,位运算,思维推导),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

  • 题目描述
    • 输入格式
    • 输出格式
    • 样例输入1
    • 样例输出1
    • 样例输入2
    • 样例输出2
    • 提交链接
    • 提示
  • 解析
  • 参考代码

题目描述

小苯有一个容量为 k k k 的背包,现在有 n n n 个物品,每个物品有一个体积 v v v 和价值 w w w,他想知道在体积不超过 k k k 的前提下,他最多能装价值为多少的物品。

本问题中,物品的总体积定义为所装物品的体积的 &(按位与),总价值也定义为所装物品的价值的 &(按位与)。

(如果不选物品,则价值为 0,所占体积也为 0。)

输入格式

输入包含 n + 1 n+1 n+1 行。

第一行两个正整数 n , k ( 1 ≤ n ≤ 2 ∗ 1 0 3 , 0 ≤ k ≤ 2 ∗ 1 0 3 ) n,k(1 \leq n \leq 2*10^3,0 \leq k \leq 2 * 10^3) n,k(1n2103,0k2103)分别表示物品个数和背包容量。

接下来 n n n 行,每行两个正整数 v i , w i ( 0 ≤ v i , w i ( 0 ≤ v i , w i ≤ 2 ∗ 1 0 3 ) ) v_i,w_i(0 \leq v_i,w_i(0 \leq v_i,w_i \leq 2 * 10^3)) vi,wi(0vi,wi(0vi,wi2103)) ,表示每个物品的体积和价值。

输出格式

输出包含一行一个整数,表示能装的最大价值。

样例输入1

3 1
7 3
10 7
9 6

样例输出1

2

样例输入2

3 2
7 3
10 7
9 6

样例输出2

3

提交链接

https://hydro.ac/d/lp728/p/23

提示

样例解释 1 1 1
选择第一个和第三个物品。
体积为:7 & 9 = 1
价值为:3 & 6 = 2。
可以证明不存在比 2 2 2 更大的价值。

样例解释 2 2 2
选择第一个和第二个物品。

解析

& 操作的特点,越 & 越小。

现在需要找到最大价值, 设其为 a n s ans ans

v a l u e [ 1 ] value[1] value[1] & v a l u e [ 2 ] value[2] value[2] & … = a n s ans ans,可以得到: a n s ans ans & v a l u e [ i ] value[i] value[i] = a n s ans ans ( a n s ans ans 在任意一位的 1 1 1, 每个 v a l u e value value 在对应位上都有)

体积是选的越多越可行, 所以可以枚举答案。

然后按 ans & value[i] = ans 这个条件,选出所有物品

计算出这些物品的总体积, 如果满足容量 k k k 限制, 则找到一个可行解。

参考代码

#include<bits/stdc++.h>
using namespace std;
const int maxn = 2e3 + 9;
int n , k , v[maxn] , w[maxn] , mx;
int main()
{cin >> n >> k;for(int i = 1; i <= n; i++)cin >> v[i] >> w[i];    //体积  价值for(int s = 2000; s >= 0; s--)  //枚举答案  答案不会超过最大的wi{int weight = (1 << 20) - 1; //按位与的初始条件 for(int i = 1; i <= n; i++){if((s & w[i]) == s)  //可以选的物品weight = weight & v[i];  //体积按位与}if(weight <= k){mx = s;break;}    }cout << mx;return 0;
}

这篇关于小苯的01背包easy(枚举,位运算,思维推导)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1003058

相关文章

poj2576(二维背包)

题意:n个人分成两组,两组人数只差小于1 , 并且体重只差最小 对于人数要求恰好装满,对于体重要求尽量多,一开始没做出来,看了下解题,按照自己的感觉写,然后a了 状态转移方程:dp[i][j] = max(dp[i][j],dp[i-1][j-c[k]]+c[k]);其中i表示人数,j表示背包容量,k表示输入的体重的 代码如下: #include<iostream>#include<

hdu2159(二维背包)

这是我的第一道二维背包题,没想到自己一下子就A了,但是代码写的比较乱,下面的代码是我有重新修改的 状态转移:dp[i][j] = max(dp[i][j], dp[i-1][j-c[z]]+v[z]); 其中dp[i][j]表示,打了i个怪物,消耗j的耐力值,所得到的最大经验值 代码如下: #include<iostream>#include<algorithm>#include<

csu(背包的变形题)

题目链接 这是一道背包的变形题目。好题呀 题意:给n个怪物,m个人,每个人的魔法消耗和魔法伤害不同,求打死所有怪物所需的魔法 #include<iostream>#include<algorithm>#include<cstring>#include<stack>#include<queue>#include<set>//#include<u>#include<map

hdu1011(背包树形DP)

没有完全理解这题, m个人,攻打一个map,map的入口是1,在攻打某个结点之前要先攻打其他一个结点 dp[i][j]表示m个人攻打以第i个结点为根节点的子树得到的最优解 状态转移dp[i][ j ] = max(dp[i][j], dp[i][k]+dp[t][j-k]),其中t是i结点的子节点 代码如下: #include<iostream>#include<algorithm

hdu1171(母函数或多重背包)

题意:把物品分成两份,使得价值最接近 可以用背包,或者是母函数来解,母函数(1 + x^v+x^2v+.....+x^num*v)(1 + x^v+x^2v+.....+x^num*v)(1 + x^v+x^2v+.....+x^num*v) 其中指数为价值,每一项的数目为(该物品数+1)个 代码如下: #include<iostream>#include<algorithm>

【Prometheus】PromQL向量匹配实现不同标签的向量数据进行运算

✨✨ 欢迎大家来到景天科技苑✨✨ 🎈🎈 养成好习惯,先赞后看哦~🎈🎈 🏆 作者简介:景天科技苑 🏆《头衔》:大厂架构师,华为云开发者社区专家博主,阿里云开发者社区专家博主,CSDN全栈领域优质创作者,掘金优秀博主,51CTO博客专家等。 🏆《博客》:Python全栈,前后端开发,小程序开发,人工智能,js逆向,App逆向,网络系统安全,数据分析,Django,fastapi

hdu 2602 and poj 3624(01背包)

01背包的模板题。 hdu2602代码: #include<stdio.h>#include<string.h>const int MaxN = 1001;int max(int a, int b){return a > b ? a : b;}int w[MaxN];int v[MaxN];int dp[MaxN];int main(){int T;int N, V;s

uva 575 Skew Binary(位运算)

求第一个以(2^(k+1)-1)为进制的数。 数据不大,可以直接搞。 代码: #include <stdio.h>#include <string.h>const int maxn = 100 + 5;int main(){char num[maxn];while (scanf("%s", num) == 1){if (num[0] == '0')break;int len =

uva 10014 Simple calculations(数学推导)

直接按照题意来推导最后的结果就行了。 开始的时候只做到了第一个推导,第二次没有继续下去。 代码: #include<stdio.h>int main(){int T, n, i;double a, aa, sum, temp, ans;scanf("%d", &T);while(T--){scanf("%d", &n);scanf("%lf", &first);scanf

hdu 2489 (dfs枚举 + prim)

题意: 对于一棵顶点和边都有权值的树,使用下面的等式来计算Ratio 给定一个n 个顶点的完全图及它所有顶点和边的权值,找到一个该图含有m 个顶点的子图,并且让这个子图的Ratio 值在所有m 个顶点的树中最小。 解析: 因为数据量不大,先用dfs枚举搭配出m个子节点,算出点和,然后套个prim算出边和,每次比较大小即可。 dfs没有写好,A的老泪纵横。 错在把index在d