小苯的排列构造,小苯的01背包(easy),小苯的01背包(hard)

简介: 小苯的排列构造,小苯的01背包(easy),小苯的01背包(hard)

小苯的排列构造

题目描述

运行代码

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define N 1000050
int i,j,k,n,m,t,a[N],b[N],f[N],l[N];
bool v[N];
int main(){
  cin>>n;
  for(i=1;i<=n;i++)
        cin>>a[i];
  v[0]=1;
  for(i=1;i<=n;i++){
    if(a[i-1]%a[i])
        {
            cout<<-1;
            return 0;
        }   
    while(v[l[a[i]]])
            l[a[i]]+=a[i];
    v[l[a[i]]]=1;
        f[i]=l[a[i]];
  }
  for(i=1;i<=n;i++)
        cout<<f[i]<<' ';
}

代码思路

  1. 读取整数序列 a[1], a[2], ..., a[n]
  2. 遍历序列,对于每个 a[i],确保 a[i] 能够整除其前一个数 a[i-1](除了第一个数 a[1],因为它没有前一个数)。
  3. 使用一个数组 l 来存储每个数 x 的当前可能位置或标签。例如,l[x] 表示当前值为 x 的数应该被放置在哪个位置。
  4. 使用一个布尔数组 v 来标记哪些位置已经被使用了。
  5. 对于每个 a[i]:如果 a[i] 不能整除其前一个数(除了第一个数 a[1]),则输出 -1 并终止程序。否则,在 l[a[i]] 开始,向后查找第一个未被使用的位(即 v[l[a[i]]]false 的位置)。将找到的位置标记为已使用(v[l[a[i]] + k*a[i]] = true,其中 k 是使得该位置未被使用的最小整数)。将 f[i] 设置为找到的位置 l[a[i]] + k*a[i]
  6. 输出所有的 f[i]

小苯的01背包(easy)

题目描述

运行代码

#include <iostream>
using namespace std;
const int N = 2e5+5;
int v[N],w[N];
int ans;
void solve()
{
    int n,k;
    cin>>n>>k;
    for(int i=0;i<n;i++)
        cin>>v[i]>>w[i];
    for(int i=30;i>=0;i--){
        int sum=ans|(1<<i);
        int v_sum=(1<<30)-1;
        for(int j=0;j<n;j++){
            if((w[j]&sum)==sum) 
                v_sum&=v[j];
        }
        if(v_sum<=k) ans=sum;
    }
    cout<<ans<<endl;
    return;
}
int main()
{
  int f= 1;
  while(f--)
        solve();
  return 0;
}

代码思路

  1. 输入处理:首先读取两个整数nk,表示物品数量和目标价值。然后读取每个物品的价值v[i]和属性w[i]
  2. 位运算优化的动态规划
  • 外层循环从30(即二进制最高位)降到0,这是因为假设属性的位数最多为30位(由(1<<30)-1暗示)。
  • 对于当前位i,计算当前最优解ans加上这一位后的值sum
  • 初始化v_sum(1<<30)-1,代表所有可能的属性集合。
  • 遍历所有物品,检查当前物品的属性集合w[j]是否包含sum的所有位(即w[j] & sum == sum),如果是,则将该物品的价值集合(视为一个二进制位集合)与v_sum进行按位与操作,这样可以逐步筛选出满足条件的最小价值集合。
  • 如果经过上述筛选后得到的v_sum小于等于目标价值k,说明加入这一位是可行的,更新当前最优解ans = sum
  1. 输出结果:最后输出得到的最大属性集合所对应的二进制值ans
  2. 主函数:主函数中通过一个变量f控制解决问题的次数,这里f=1意味着只解决一次问题,然后调用solve()函数执行上述逻辑。

小苯的01背包(hard)

题目描述

运行代码

#include <iostream>
using namespace std;
typedef long long ll;
const int N=2e5+5;
int read() {
    int x = 0, f = 1;
    char c = getchar();
    while(c < '0' || c > '9')
        f = (c == '-') ? -1 : 1, c = getchar();
    while(c >= '0' && c <= '9')
        x = x * 10 + c - 48, c = getchar();
    return f * x;
}
int a[N], v[N], w[N], b[N], n, k;
bool check(int x) {
    int tot = 0;
    for(int i = 1; i <= n; i++)
        if((x & w[i]) == x)
            b[++tot] = i;
    int c = (1 << 31) - 1;
    for(int i = 1; i <= tot; i++)
        c &= v[b[i]];
    if(c <= k)
        return 1;
    return 0;
}
signed main() {
    n = read(), k = read();
    for(int i = 1; i <= n; i++)
        v[i] = read(), w[i] = read();
    int ans = 0;
    for(int i = 30; i >= 0; i--) {
        if(check(ans | (1 << i)))
            ans |= 1 << i;
    }
    cout << ans;
}

代码思路

  1. 输入处理:
  • 使用read()函数自定义读取整数,支持负数,提高了输入效率。
  • 读取项目数量n和价值阈值k,以及每个项目的具体价值v[i]和属性w[i]
  1. check函数:
  • 输入一个整数x,表示当前考虑的属性集合。
  • 遍历所有项目,如果项目i的属性集合w[i]x的子集(即(x & w[i]) == x),则将该项目的索引存入数组b[]
  • 计算所有符合条件的项目价值集合的交集(通过按位与运算),并检查这个交集的值是否不大于k。如果满足条件,返回true;否则,返回false
  1. 主函数逻辑:
  • 初始化答案ans为0,表示当前考虑的最优属性集合。
  • 从最高位到最低位遍历(即从第30位到第0位),对于每一位:尝试将这一位置为1(即在当前最优解基础上增加这一位的属性),然后检查这一改变是否仍然满足总价值不超过k的条件,这通过调用check()函数完成。如果满足条件,就保留这一位的修改(即这一位在最终解中应为1);如果不满足,就尝试下一位。
  • 最终输出得到的属性集合的二进制表示ans

利用了位运算来高效地处理集合的合并与判断,通过逐位检查的方式构建出满足条件的最优属性集合,相比直接的暴力枚举或者传统动态规划方法,在处理大规模数据时能显著提高效率。

目录
相关文章
|
弹性计算 网络协议 Linux
Xshell使用SSH远程登录阿里云ECS服务器CentOS7
Xshell使用SSH远程登录阿里云ECS服务器CentOS7
|
安全 物联网 5G
物联网卡
随着科技飞速发展,物联网作为新一代信息技术的核心部分,正深刻改变生活、工作和社会结构。物联网卡是设备接入互联网的关键媒介,推动了智慧城市、工业4.0、智能家居、远程医疗、智能交通等领域的创新。它具备定制化服务、广覆盖与稳定性、大容量与高并发及安全管理等特点。物联网卡广泛应用于智能安防、智能制造、智能家居、远程医疗和智能交通等领域,提升效率和体验。尽管面临网络覆盖不足、数据安全等挑战,但通过加强基础设施建设、强化数据安全、推动标准化和创新服务模式,物联网卡将引领万物互联新时代,成为连接未来的桥梁。
物联网卡
|
人工智能 算法 数据安全/隐私保护
基于文档智能和百炼平台的RAG应用-部署实践有感
本文对《文档智能 & RAG让AI大模型更懂业务》解决方案进行了详细测评,涵盖实践原理理解、部署体验、LLM知识库优势及改进空间、适用业务场景等方面。测评指出,该方案在提升AI大模型对特定业务领域的理解和应用能力方面表现突出,但需在技术细节描述、知识库维护、多语言支持、性能优化及数据安全等方面进一步完善。
535 1
|
前端开发 JavaScript 编译器
前端开发新视界:2024年的五大技术趋势
【10月更文挑战第3天】前端开发新视界:2024年的五大技术趋势
888 0
|
供应链 区块链 数据安全/隐私保护
区块链技术基础:从去中心化到智能合约
区块链技术基础:从去中心化到智能合约
251 0
|
移动开发 搜索推荐 Android开发
安卓与iOS开发:一场跨平台的技术角逐
在移动开发的广阔舞台上,两大主角——安卓和iOS,持续上演着激烈的技术角逐。本文将深入浅出地探讨这两个平台的开发环境、工具和未来趋势,旨在为开发者揭示跨平台开发的秘密,同时激发读者对技术进步的思考和对未来的期待。
|
Android开发 Kotlin
安卓Jetpack Compose+Kotlin, 使用ExoPlayer播放多个【本地】音频,播放完随机播放下一首,遇到播放错误,也自动播放下一首
使用Kotlin和Jetpack Compose开发的安卓应用中,实现了两个EvoPlayer同时播放res/raw目录下的音频。一个音轨播放人声(顺序播放),另一个播放背景音乐(随机播放)。每个音轨都有独立的播放和停止控制,且在播放结束或遇到错误时会自动切换到下一首。MediaPlayer置于ViewModel中,UI界面包含播放和停止按钮,控制两个音轨。每次切换音频前,还会随机调整播放速度在0.9到1.2之间。代码示例展示了如何创建ViewModel和UI以实现这一功能。
|
Linux 程序员
01 官网下载各种CentOS教程(超详细版)
01 官网下载各种CentOS教程(超详细版)
1046 0
|
存储 C语言
C语言:char与unsigned char类型数据的范围
unsigned char 的范围是 0~255,当 i=255 时,i++变为0,从0到255无限循环,因此程序运行结果为死循环
985 0