【补题日记】[2022杭电暑期多校1]C-Backpack

Pro

https://acm.hdu.edu.cn/showproblem.php?pid=7140

Sol

f i , j , k f_{i,j,k} fi,j,k表示前i个物品,异或和为j,体积为k的方案是否存在

则状态转移方程为 f i , j , k = f i − 1 , j , k ∣ f i − 1 , j ⊕ v , k − w f_{i,j,k}=f_{i-1,j,k}|f_{i-1,j\oplus v,k-w} fi,j,k=fi1,j,kfi1,jv,kw

使用滚动数组将第一维滚掉,用bitset优化掉最后一维

关于下面代码中的g[j]=f[j]<<x说明:此处使用左移可以理解为,当第 i i i次移动 v i v_i vi时,最终总的移动为 ∑ i = 1 n v i x i , x i = 0 / 1 \sum_{i=1}^n v_ix_i,x_i={0/1} i=1nvixi,xi=0/1。如果总的移动次数为 m m m,也就是bitset的第 m m m位为1,就说明可以恰好装满整个背包。

Code

//By cls1277
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
#define Fo(i,a,b) for(LL i=(a); i<=(b); i++)
#define Ro(i,b,a) for(LL i=(b); i>=(a); i--)
#define Eo(i,x,_) for(LL i=head[x]; i; i=_[i].next)
#define Ms(a,b) memset((a),(b),sizeof(a))
#define endl '\n'

const LL maxn = 1030;
bitset<maxn> f[maxn], g[maxn];

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    #ifdef DEBUG
    freopen("data.txt","r",stdin);
    #endif
    LL t; cin>>t;
    while(t--) {
        LL n, m; cin>>n>>m;
        Fo(i,0,1023) f[i].reset();
        f[0][0] = 1;
        Fo(i,1,n) {
            LL x, y; cin>>x>>y;
            Fo(j,0,1023) g[j]=f[j]<<x;
            Fo(j,0,1023) f[j]|=g[j^y];
        }
        LL ans = -1;
        Ro(i,1023,0) {
            if(f[i][m]) {
                ans = i;
                break;
            }
        }
        cout<<ans<<endl;
    }
    return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
0-1背包问题是一个经典的组合优化问题,可以使用回溯法进行求解。TSP问题是一个旅行商问题,也可以使用回溯法进行求解。 下面是利用回溯法编程求解0-1背包问题的步骤: 1. 定义一个函数backpack,该函数接受四个参数:items、max_weight、current_weight和current_value。其中,items是一个列表,表示物品的重量和价值;max_weight是背包的最大容量;current_weight是当前背包中物品的总重量;current_value是当前背包中物品的总价值。 2. 在函数中,首先判断是否已经考虑完了所有的物品,如果是,则返回当前背包中物品的总价值。 3. 如果还有物品没有考虑,则分别考虑将该物品放入背包和不放入背包两种情况。 4. 如果将该物品放入背包后,背包的总重量不超过最大容量,则计算放入该物品后的总价值,并递归调用backpack函数,将当前物品的重量和价值加入current_weight和current_value中。 5. 如果不将该物品放入背包,则直接递归调用backpack函数。 6. 返回两种情况中的最大值。 下面是利用回溯法编程求解TSP问题的步骤: 1. 定义一个函数tsp,该函数接受三个参数:graph、current_path和current_cost。其中,graph是一个二维列表,表示城市之间的距离;current_path是一个列表,表示当前已经走过的路径;current_cost是当前已经走过的路径的总长度。 2. 在函数中,首先判断是否已经走过了所有的城市,如果是,则将当前路径的总长度加上最后一个城市到起点的距离,并返回该值。 3. 如果还有城市没有走过,则遍历所有未走过的城市,分别将该城市加入current_path中,并递归调用tsp函数,计算加入该城市后的路径长度。 4. 递归返回后,将current_path中最后一个城市弹出,回溯到上一个状态。 5. 返回所有情况中的最小值。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

cls1277

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值