【习题·搜索】Bookcase(IDA*)

2023-10-13 13:08
文章标签 搜索 ida 习题 bookcase

本文主要是介绍【习题·搜索】Bookcase(IDA*),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

题目描述

有N(1 <=N <= 15)本书,每本与每本的高度都不一样。现在可以按照以下的办法整理书:抽出一摞书,再保持原来的顺序插进一个位置。这样的话我们称之为“一次操作”。现在你需要求出至少需要经过几次操作才能让书变成按高度升序的状态。如果需要5次或者多于5次,只需要输出“5 or more”。

题解

如果暴力考虑搜索:我们将 L L L- R R R的书放到 K K K后面,此时一定满足 K &gt; R K&gt;R K>R,否则与先前重复枚举;此时这些书的序列就会有:序列 L L L- R R R和序列 R + 1 R+1 R+1- K K K进行交换,我们使用临时数组存储即可。

因为输出不超过五部,我们需要使用迭代加深搜索。

然后考虑能否设计出一个适当的估价函数利用IDA*算法解决;显然每次进行移动操作的时候,会有三个点的后继发生改变,即 L − 1 L-1 L1 R R R K K K的后继;如果满足 a [ i ] + 1 = a [ i + 1 ] a[i]+1=a[i+1] a[i]+1=a[i+1],则 i + 1 i+1 i+1 i i i的正确后继,如若每一个序列的错误后继为 t o t tot tot,则可以令函数值 = ⌈ t o t ⌉ =\lceil tot \rceil =tot,即每一次最多修改三个后继使其变正确。

代码

#include <cstdio>
#include <cstring>
#include <iostream>using namespace std;int n;
int a[20];inline int read()
{int s=0;char c=getchar();while (c<'0' || c>'9') c=getchar();while (c>='0' && c<='9') s=s*10+c-48, c=getchar();return s; 	
}inline int func(void)
{int tot=0;for (int i=1;i<=n;++i) if (a[i]+1!=a[i+1]) tot ++;return tot;
}void change(int L,int R,int K)
{int t[20] = {}, c=0;for (int i=R+1;i<=K;++i) t[++c]=a[i];for (int i=L;i<=R;++i) t[++c]=a[i];for (int i=L;i<=K;++i) a[i]=t[i-L+1]; 
}bool dfs(int deep,int MAXD)
{int b[20]={}; if (deep==MAXD){if (!func()) return 1;return 0;}int G=func();G=G%3 ? G/3+1 : G/3;if (deep+G>=5) return 0; //IDA*剪枝memcpy(b,a,sizeof(b));for (int L=1;L<=n;++L) for (int R=L;R<=n;++R) for (int K=R+1;K<=n;++K) {//交换 L - R 和  R+1 - Kchange(L,R,K);if (dfs(deep+1,MAXD)) return 1;memcpy(a,b,sizeof(a));} return 0;
}
int main(void)
{freopen("b.in","r",stdin);freopen("b.out","w",stdout);int T;T=read();Again:bool flag=0;n=read();a[n+1]=n+1;for (int i=1;i<=n;++i) a[i]=read();for (int i=0;i<=4;++i)if (dfs(0,i)) {printf("%d\n",i);flag=1;break;}if (!flag) puts("5 or more");if (--T) goto Again;return 0;
} 

这篇关于【习题·搜索】Bookcase(IDA*)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



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

相关文章

认识、理解、分类——acm之搜索

普通搜索方法有两种:1、广度优先搜索;2、深度优先搜索; 更多搜索方法: 3、双向广度优先搜索; 4、启发式搜索(包括A*算法等); 搜索通常会用到的知识点:状态压缩(位压缩,利用hash思想压缩)。

hdu1240、hdu1253(三维搜索题)

1、从后往前输入,(x,y,z); 2、从下往上输入,(y , z, x); 3、从左往右输入,(z,x,y); hdu1240代码如下: #include<iostream>#include<algorithm>#include<string>#include<stack>#include<queue>#include<map>#include<stdio.h>#inc

【C++ Primer Plus习题】13.4

大家好,这里是国中之林! ❥前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站。有兴趣的可以点点进去看看← 问题: 解答: main.cpp #include <iostream>#include "port.h"int main() {Port p1;Port p2("Abc", "Bcc", 30);std::cout <<

hdu 4517 floyd+记忆化搜索

题意: 有n(100)个景点,m(1000)条路,时间限制为t(300),起点s,终点e。 访问每个景点需要时间cost_i,每个景点的访问价值为value_i。 点与点之间行走需要花费的时间为g[ i ] [ j ] 。注意点间可能有多条边。 走到一个点时可以选择访问或者不访问,并且当前点的访问价值应该严格大于前一个访问的点。 现在求,从起点出发,到达终点,在时间限制内,能得到的最大

AI基础 L9 Local Search II 局部搜索

Local Beam search 对于当前的所有k个状态,生成它们的所有可能后继状态。 检查生成的后继状态中是否有任何状态是解决方案。 如果所有后继状态都不是解决方案,则从所有后继状态中选择k个最佳状态。 当达到预设的迭代次数或满足某个终止条件时,算法停止。 — Choose k successors randomly, biased towards good ones — Close

hdu4277搜索

给你n个有长度的线段,问如果用上所有的线段来拼1个三角形,最多能拼出多少种不同的? import java.io.BufferedInputStream;import java.io.BufferedReader;import java.io.IOException;import java.io.InputStream;import java.io.InputStreamReader;

HDU 1560 IDA*

给出n个串,求最短公共串(不要求连续) h ,最少还需要多长来匹配所有。 import java.io.BufferedReader;import java.io.InputStream;import java.io.InputStreamReader;import java.io.PrintWriter;import java.math.BigInteger;imp

浙大数据结构:04-树7 二叉搜索树的操作集

这道题答案都在PPT上,所以先学会再写的话并不难。 1、BinTree Insert( BinTree BST, ElementType X ) 递归实现,小就进左子树,大就进右子树。 为空就新建结点插入。 BinTree Insert( BinTree BST, ElementType X ){if(!BST){BST=(BinTree)malloc(sizeof(struct TNo

第六章习题11.输出以下图形

🌏个人博客:尹蓝锐的博客 希望文章能够给到初学的你一些启发~ 如果觉得文章对你有帮助的话,点赞 + 关注+ 收藏支持一下笔者吧~ 1、题目要求: 输出以下图形

【C++ Primer Plus习题】12.2

大家好,这里是国中之林! ❥前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站。有兴趣的可以点点进去看看← 问题: 解答: main.cpp #include <iostream>#include "String.h"using namespace std;int main(){String s1(" and I am a