DFS之迭代加深+双向DFS+IDA*

news2025/1/23 17:46:57

迭代加深:

搜索范围一层一层扩大,可以快速某些分支比较深,但是答案比较浅的问题。

https://www.acwing.com/problem/content/172/

通过观察可以发现:

1.搜索时最坏情况可能搜到100层,比较深,但是答案应该比较浅,于是考虑迭代加深。

2.剪枝:

(1)搜索顺序:我们从后往前枚举

(2)等效冗余:枚举前面选2个,等值的不用重复算。

AC代码:

#include<bits/stdc++.h>
using namespace std;
int path[110];
int n;
int dfs(int c,int len){
    if(path[c]==n&&c==len) return 1;
    if(c>=len) return 0;
    bool st[500]={0};
    for(int i=c;i>=1;i--){
        for(int j=i;j>=1;j--){
            int ck=path[i]+path[j];
            if(ck>n) continue;
            if(st[ck]) continue;
            if(ck<=path[c]) continue;
            st[ck]=1;
            path[c+1]=ck;
            if(dfs(c+1,len)) return 1;
        }
    }
    return 0;
}
int main(){
    while(cin>>n,n){
        path[1]=1;
        int len=1;
        while(dfs(1,len)==0) len++;
        for(int i=1;i<=len;i++){
            cout<<path[i]<<" ";
        }
        cout<<endl;
    }
}

双向DFS:

https://www.acwing.com/problem/content/173/

我们先想想直接DFS,那么差不多是1e12多的级别,于是我们对于N考虑枚举前K个,对于剩下的N-K个我们枚举一个再二分一下前K个中与它最接近W的值即可。

我们考虑复杂度:2_{}^{K}+2_{}^{N-K}*K,我们考虑选取合适的K来最小化复杂度即可(一般直接对半开即可)

AC代码:

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll w1,n;
const int N=(1<<24);
ll a[101];
ll w[N];
ll cnt=0;
ll ans=0;
void dfs1(ll u,ll len,ll fk){
    if(u==len+1){
        w[++cnt]=fk;
        return;
    }
    dfs1(u+1,len,fk);
    if(fk+a[u]<=w1) dfs1(u+1,len,fk+a[u]);
}
void dfs2(ll u,ll len,ll fk){
    if(u==len+1){
        ll l=0,r=cnt-1;
        while(l<r){
            int mid=(l+r+1)/2;
            if(fk+w[mid]<=w1) l=mid;
            else r=mid-1;
        }
        ans=max(ans,fk+w[l]);
        return;
    }
    dfs2(u+1,len,fk);
    if(fk+a[u]<=w1) dfs2(u+1,len,fk+a[u]);
}
int main(){
    cin>>w1>>n;
    for(int i=1;i<=n;i++) cin>>a[i];
    sort(a+1,a+n+1);
    reverse(a+1,a+n+1);
    ll len=n/2;
    dfs1(1,len,0);
    sort(w+1,w+cnt+1);
    cnt=unique(w+1,w+cnt+1)-w;
    //for(int i=1;i<=cnt-1;i++) cout<<w[i]<<" "; 
    dfs2(len+1,n,0);
    cout<<ans;
}

IDA*:

其实就是迭代加深上加了个评估函数,假如预估到最深层还是不行就退出。

https://www.acwing.com/problem/content/182/

整体就是一个迭代加深,现在我们考虑构造评估函数:

类似逆序对,我们考虑连接对(每一个后继点为前一个+1视为正确),每一次操作一共断开3个连接点,因此最多一次矫正3个。

于是我们设当前错误的连接对有tot个,那么评估函数就是:(tot+2)/3

下面是AC代码:

#include<bits/stdc++.h>
using namespace std;
int t,n;
int a[16];
int dep[6][16];
int f()
{
    int res = 0;
    for (int i = 1; i + 1 <= n; i ++ )
        if (a[i + 1] != a[i] + 1)
            res ++ ;
    return (res + 2) / 3;
}

bool check()
{
    for (int i = 1; i <= n; i ++ )
        if (a[i] != i)
            return false;
    return true;
}
int dfs(int d,int len){
    if(d+f()>len) return 0;
    if(check()) return 1;
    for(int l=1;l<=n;l++){
        for(int r=l;r<=n;r++){
            for(int k=r+1;k<=n;k++){
                memcpy(dep[d], a, sizeof a);
                int x,y;
                for(x=r+1,y=l;x<=k;x++,y++) a[y]=dep[d][x];
                for(x=l;x<=r;x++,y++) a[y]=dep[d][x];
                if(dfs(d+1,len)) return 1;
                memcpy(a, dep[d], sizeof a);
            }
        }
    }
    return 0;
}
int main(){
    cin>>t;
    while(t--){
        cin>>n;
        for(int i=1;i<=n;i++) cin>>a[i];
        int len=0;
        while(len<5&&!dfs(0,len)) len++;
        if(len>=5) cout<<"5 or more"<<endl;
        else cout<<len<<endl;
    }
}

https://www.acwing.com/problem/content/183/

和上一题类似,我们直接考虑评估函数的构造:

我们发现,假如中间8个里出现次数最多的是cnt个,那么我们最少通过8-cnt来实现。

同时,为了操作的方便,我们采用打表的方式:

具体来说,我们人为的对这个“容器”的位置标号(从上到下,从左到右),同时我们把每一次操作对应的编号记下来,这样每次操作都可以快速找到进行操作位置的下标了。

AC代码:

/*
      0     1
      2     3
4  5  6  7  8  9  10
      11    12
13 14 15 16 17 18 19
      20    21
      22    23
*/
#include<bits/stdc++.h>
using namespace std;
const int N = 24;
int q[N];
int op[8][7] = {
    {0, 2, 6, 11, 15, 20, 22},
    {1, 3, 8, 12, 17, 21, 23},
    {10, 9, 8, 7, 6, 5, 4},
    {19, 18, 17, 16, 15, 14, 13},
    {23, 21, 17, 12, 8, 3, 1},
    {22, 20, 15, 11, 6, 2, 0},
    {13, 14, 15, 16, 17, 18, 19},
    {4, 5, 6, 7, 8, 9, 10}
};
int center[8] = {6, 7, 8, 11, 12, 15, 16, 17};
int opposite[8] = {5, 4, 7, 6, 1, 0, 3, 2};
int path[100];
int f()
{
    int sum[4]={0};
    for (int i = 0; i < 8; i ++ ) sum[q[center[i]]] ++ ;
    int s = 0;
    for (int i = 1; i <= 3; i ++ ) s = max(s, sum[i]);
    return 8 - s;
}
void operation(int x)
{
    int t = q[op[x][0]];
    for (int i = 0; i < 6; i ++ ) q[op[x][i]] = q[op[x][i + 1]];
    q[op[x][6]] = t;
}
bool dfs(int depth, int max_depth, int last)
{
    if (depth + f() > max_depth) return false;
    if (f()==0) return true;
    for (int i = 0; i < 8; i ++ )
    {
        if (opposite[i] == last) continue;
        operation(i);
        path[depth] = i;
        if (dfs(depth + 1, max_depth, i)) return true;
        operation(opposite[i]);
    }
    return false;
}

int main()
{
    while (scanf("%d", &q[0]), q[0])
    {
        for (int i = 1; i < N; i ++ ) scanf("%d", &q[i]);
        int depth = 0;
        while (!dfs(0, depth, -1)) depth ++ ;
        if (!depth) printf("No moves needed");
        for (int i = 0; i < depth; i ++ ) printf("%c", 'A' + path[i]);
        printf("\n%d\n", q[6]);
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1978063.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【Javax.Validation】✈️整合 SpringBoot 实现运行时的参数校验

目录 &#x1f44b;前言 &#x1f440;一、Validation 依赖 &#x1f4eb;二、常见注解 2.1 不需要指定注解参数 2.2 需要声明注解参数 &#x1f49e;️三、项目测试注解使用 3.1 依赖引入 3.2 实体类创建 3.3 创建对外接口 3.4 模拟请求 &#x1f331;四、章末 &#x1f…

RSS 2024 清华大学交叉院高阳提出高效的机器人操作技能学习方法

机器人掌握一项新技能需要几步&#xff1f; 一般来说&#xff0c;在传统机器学习方法中&#xff0c;通常使用演示学习的方式教会机器人掌握新技能&#xff0c;然而&#xff0c;收集高质量的演示数据成本高且耗时&#xff0c;一定程度上影响了机器人技能学习进度。尽管视频作为…

⭕️【论文阅读】《Interactive Class-Agnostic Object Counting》

[2309.05277] Interactive Class-Agnostic Object Counting (arxiv.org) code&#xff1a; cvlab-stonybrook/ICACount: [ICCV23] Official Pytorch Implementation of Interactive Class-Agnostic Object Counting (github.com) 目录 Abstract Abstract 我们提出了一个新…

linux学习记录(一)--------目录及文件操作

文章目录 前言Linux目录及文件操作1.Linux目录结构2.常用的Linux命令3.vi编辑器的简单使用4.vi的两个模式 前言 小白学习linux记录有错误随时指出~ Linux目录及文件操作 Linux采用Shell命令->操作文件 1.Linux目录结构 根目录&#xff1a;/ 用户目录&#xff1a;~或者/ho…

float转uint8_t数组

float类型在x64中占4字节&#xff0c;需要占据uint8_t数组大小4字节 数据float类型3.14&#xff0c;在内存中4字节地址应该为0x4048f5c3 如果直接使用memcpy内存复制&#xff0c;0xc3会放在数组下标小的位置

〖任务1〗ROS2 jazzy Linux Mint 22 安装教程

前言&#xff1a; 本教程在Linux系统上使用。 目录 一、linux安装二、linux VPN安装三、linux anaconda安装&#xff08;可选&#xff09;四、linux ROS2 安装五、rosdep init/update 解决方法六、安装GUI 一、linux安装 移动硬盘安装linux&#xff1a;[LinuxToGo教程]把ubunt…

代码随想录算法训练营第43天|LeetCode 300.最长递增子序列、674. 最长连续递增序列、718. 最长重复子数组

1. LeetCode 300.最长递增子序列 题目链接&#xff1a;https://leetcode.cn/problems/longest-increasing-subsequence/description/ 文章链接&#xff1a;https://programmercarl.com/0300.最长上升子序列.html 视频链接&#xff1a;https://www.bilibili.com/video/BV1ng411J…

进阶SpringBoot之 Spring 官网或 IDEA 快速构建项目

SpringBoot 就是一个 JavaWeb 的开发框架&#xff0c;约定大于配置 程序 数据结构 算法 微服务架构是把每个功能元素独立出来&#xff0c;再动态组合&#xff0c;是对功能元素的复制 这样做可以节省调用资源&#xff0c;每个功能元素的服务都是一个可替代、可独立升级的软…

从地铁客流讲开来:超一线城市的客运量特征

这篇我们把视角聚焦在四大超一线城市&#xff0c;北上广深&#xff0c;我们来看看这些城市地铁客运量的异同&#xff0c;这里放一个背景2024年6月8日—6月10日是我国农历的端午节&#xff0c;我们看图说话&#xff0c;相同的特征&#xff1a;1.四大一线城市客流都在周五达到客运…

数学建模--蒙特卡罗随机模拟

目录 蒙特卡罗方法的基本原理 蒙特卡罗方法在优化中的应用 蒙特卡罗方法的优势与局限 优势 局限 典型应用案例 Python代码示例 ​编辑 结论 蒙特卡罗方法在数学建模中的具体应用案例有哪些&#xff1f; 如何改进蒙特卡罗方法以提高计算效率和精度&#xff1f; 蒙特…

如何使你的mermaid流程图里的某一段文字加粗、变斜、成为上下标……

目录 参考的链接开头1.加粗&#xff0c;*斜体*与下划线2.标记,~~删除线~~与^上^~下~标3.代码片与标题4.注释与蓝色链接5.其</q>他 东西 结尾 参考的链接 HTML标签列表(按字母排序)和HTML标签列表(按功能排序) 开头 大家好&#xff0c;我叫这是我58。今天&#xff0c;我们…

【架构】客户端优化

这篇文章总结一下服务器网关及之前部分的优化&#xff0c;如客户端的优化&#xff0c;CDN/DNS等。 这里我们先谈一谈客户端缓存优化的手段。一般我们后端在说到缓存&#xff0c;第一时间想到的往往是redis&#xff0c;其实缓存在架构层次还有很多其他可以实现的地方&#xff0…

从LLM到大模型推理的最新进展

大语言模型LLM的推理引擎经过一年时间发展&#xff0c;现在主流方案收敛到了开源的vLLM和半闭源的TensorRT-LLM。 TRT-LLM基于C开发&#xff0c;有NV算子开发黑魔法加持&#xff0c;在其重点支持的场景里&#xff0c;性能可以做到极致。vLLM基于python开发&#xff0c;代码简洁…

MySQL第2讲--关系型数据库以及SQL语句分类之DDL数据库和表的操作

文章目录 前言关系型数据库&#xff08;RDBMS&#xff09;关系型数据库的特点 MySQL数据模型SQL介绍基本语法规则SQL语句的分类DDL的介绍DDL的数据库操作DDL的表操作 前言 上一节MySQL第1讲–详细安装教程和启动方法中介绍了MySQL如何安装&#xff0c;以及如何启动和客户端连接…

使用 Elastic 和 Mistral 构建多语言 RAG

作者&#xff1a;来自 Elastic Gustavo Llermaly 使用 Elastic 和 Mixtral 8x22B 模型构建多语言 RAG 应用程序。 Mixtral 8x22B 是性能最高的开放式模型&#xff0c;其最强大的功能之一是能够流利使用多种语言&#xff1b;包括英语、西班牙语、法语、意大利语和德语。 想象一…

质量属性-系统架构师(四十)

质量属性 1性能&#xff1a; 指系统响应能力。如响应时间、吞吐量。 设计策略&#xff1a;优先级队列&#xff0c;增加计算机资源&#xff0c;减少计算机开销&#xff0c;引入并发机制&#xff0c;采用资源调度。 2可靠性&#xff1a; 在一定时间内正常运行的情况下&#x…

PTA—基础编程题目集(7-21)

7-21 求特殊方程的正整数解 目录 题目描述 输入格式&#xff1a; 输出格式&#xff1a; 输入样例1&#xff1a; 输出样例1&#xff1a; 输入样例2&#xff1a; 输出样例2&#xff1a; 参考代码 总结 题目描述 本题要求对任意给定的正整数N&#xff0c;求方程X2Y2N的…

《Milvus Cloud向量数据库指南》——关于Ivy.ai:重塑沟通效率与数据安全的创新先锋

关于Ivy.ai:重塑沟通效率与数据安全的创新先锋 在数字化转型的浪潮中,Ivy.ai以其前瞻性的视野和专业团队的匠心独运,正逐步成为高等教育、医疗保健及公共部门沟通效率提升的引领者。这家企业不仅代表了人工智能技术在服务领域的最新进展,更以其旗舰产品IvyQuantum™的横空…

搬瓦工香港CMI VPS测评

搬瓦工香港cmi怎么样&#xff1f;搬瓦工香港VPS分CN2 GIA和CMI两种不同接入的网络&#xff0c;其中CMI网络的回程是强制三网全部都走移动CMI线路&#xff0c;相对CN2 GIA来说有一定的差距。实际的情况测评数据送上&#xff0c;可供参考。 CPU型号未知&#xff0c;主频2.7GHz&a…

【C++】一堆数组 冒泡排序

冒泡排序&#xff0c;一种很常见的排序法师 这章要划重点&#xff0c;很重要&#xff01;&#xff01; 排序思路为前一个元素与后一个元素比大小&#xff0c;一直循环一轮&#xff0c;找出最大/最小的那个元素后&#xff0c;进行下一轮&#xff0c;找到第二大/小的元素......…