题目链接:P2534 [AHOI2012]铁盘整理

题解:本篇为IDA*的应用,做这题前建议先做前一篇文章的题目:点这

这题中难在估值函数的确定,总的来说IDA*基本上格式都差不多,主要难在估值函数的确定上,估值函数确定的好就能很好的优化时间,我们可以发现,铁盘中的单调序列数即为我们要翻转的次数,比如12543我们需要翻转2次,恰好对应了 12,345两个单调序列,那么我们就可以用数组中单调队列是数量来代表H,即到达最终状态的操作次数,其他地方IDA*基本上都一样了

细节见代码注释:

#include<iostream>
#include<stack>
#include<list>
#include<set>
#include<vector>
#include<algorithm>
#include<math.h>
#include<numeric>
#include<map>
#include<cstring>
#include<queue>
#include<iomanip>
#include<cmath>
#include<queue>
#include <bitset>
#include<unordered_map>#ifndef local#define endl '\n'
#endif */
#define mkp make_pair
using namespace std;
using std::bitset;
typedef long long ll;
typedef long double ld;
const int inf=0x3f3f3f3f;
const ll MAXN=2e6+10;
const ll N=2e5+100;
const ll mod=1e9+7;
const ll hash_p1=1610612741;
const ll hash_p2=805306457;
const ll hash_p3=402653189;
//-----------------------------------------------------------------------------------------------------------------*/
// ll head[MAXN],net[MAXN],to[MAXN],edge[MAXN]/*流量*/,cost[MAXN]//费用;
/*
void add(ll u,ll v,ll w,ll s){to[++cnt]=v;net[cnt]=head[u];edge[cnt]=w;cost[cnt]=s;head[u]=cnt;to[++cnt]=u;net[cnt]=head[v];edge[cnt]=0;cost[cnt]=-s;head[v]=cnt;
}
struct elemt{int p,v;
};
-----------------------------------
求[1,MAXN]组合式和逆元
ll mi(ll a,ll b){ll res=1;while(b){if(b%2){res=res*a%mod;}    a=a*a%mod;b/=2;}return res;
}
ll fac[MAXN+10],inv[MAXN+10]
ll C(int m,int n){//组合式C(m,n); if(!n){return 1;}return fac[m]*(inv[n]*inv[m-n]%mod)%mod;
}
fac[0]=1;inv[0]=1;
for(ll i=1;i<=MAXN;i++){fac[i]=(fac[i-1]*i)%mod;inv[i]=mi(fac[i],mod-2);
}
---------------------------------unordered_map<int,int>mp;
//优先队列默认小顶堆 , greater<int> --小顶堆  less<int> --大顶堆
priority_queue<elemt,vector<elemt>,comp>q;
struct comp{public:bool operator()(elemt v1,elemt v2){return v1.v<v2.v;}
};set<int>::iterator it=st.begin();
*/
//emplace_back()  等于push_back(),但效率更高,传输pair时emplace_back(i,j)==push_back({i,j})
// vector<vector<int>>edge; 二维虚拟储存坐标
//-----------------------------------------------------------------------------------------------------------------*///map<int,bool>mp[N]; //emplace_back()
int dx[8]={1,1,2,2,-1,-1,-2,-2};
int dy[8]={2,-2,1,-1,2,-2,1,-1};
//目标状态
int key[5][5]={
{1,1,1,1,1},
{0,1,1,1,1},
{0,0,2,1,1},
{0,0,0,0,1},
{0,0,0,0,0}
};
int c[10][10];
int h(){//到终点的估价函数int res=0;for(int i=0;i<5;i++){for(int j=0;j<5;j++){if(key[i][j]!=c[i][j]){res++;}}}if(res){//若当前存在res个不同点,则最少也需要res-1次交换res--;}return res;
}
int success=0;//标记是否有可行解
void A_STAR(int dep,int maxdep,int x,int y){//当前深度,允许运行的最大深度,空格子坐标if(dep==maxdep){//走到底了if(h()==0){//找到可行解了success=1;}return ;}for(int i=0;i<8&&!success;i++){//枚举转移(若要记录路径可以直接用个pre数组记录转移即可)int fx=x+dx[i],fy=y+dy[i];if(fx>=0&&fx<5&&fy>=0&&fy<5){swap(c[x][y],c[fx][fy]);//更新状态if(dep+1+h()<=maxdep){//继续往下转移可能为答案的情况A_STAR(dep+1,maxdep,fx,fy);}swap(c[x][y],c[fx][fy]);//回溯状态}}
}
int main(){
/*cout<<setiosflags(ios::fixed)<<setprecision(8)<<ans<<endl;//输出ans(float)格式控制为8位小数(不含整数部分)*/
/*cout<<setprecision(8)<<ans<<endl;//输出ans(float)格式控制为8位小数(含整数部分)*/ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);//同步流int t;cin>>t;while(t--){success=0;int sx,sy;for(int i=0;i<5;i++){for(int j=0;j<5;j++){char d;cin>>d;if(d=='0'){c[i][j]=0;}else if(d=='1'){c[i][j]=1;}else{c[i][j]=2;sx=i,sy=j;}}}for(int i=0;i<=15;i++){//精髓(降低复杂度)//我们可能会在一个没有解(或解很深的地方无限递归然而题目中要求输出任何的一组解),//所以我们限制一个深度,让它去遍历更多的分支,去更广泛地求解,(其实和BFSBFS有异曲同工之妙)。A_STAR(0,i,sx,sy);if(success){cout<<i<<endl;break;}}if(!success){cout<<-1<<endl;}}return 0;
}

洛谷 P2534 [AHOI2012]铁盘整理(IDA*(dfs+迭代加深+估值函数))相关推荐

  1. 洛谷 P2534 [AHOI2012]铁盘整理

    P2534 [AHOI2012]铁盘整理 题目描述 输入输出格式 输入格式: 共两行.第一行为铁盘个数N(1<=N<=50),第二行为N个不同的正整数,分别为从上到下的铁盘的半径R.(1& ...

  2. 洛谷P2534 [AHOI2012]铁盘整理

    P2534 [AHOI2012]铁盘整理 题目描述 输入输出格式 输入格式: 共两行.第一行为铁盘个数N(1<=N<=50),第二行为N个不同的正整数,分别为从上到下的铁盘的半径R.(1& ...

  3. P2534 [AHOI2012]铁盘整理(IDA*)

    题目大意: 解题思路: 其实只要注意到,如果数字是连续的,那么第i层与第i+1层的高度差为1,而每次只能翻转1~k层,相当于只能改变第k层与第k+1层的差,即只能改变一个相邻差 IDA*步骤: 离散化 ...

  4. *【洛谷 - P1025】数的划分(dfs 或 dp 或 母函数,第二类斯特林数Stirling)

    题干: 题目描述 将整数n分成k份,且每份不能为空,任意两个方案不相同(不考虑顺序). 例如:n=7,k=3,下面三种分法被认为是相同的. 1,1,5 1,5,1 5,1,1 问有多少种不同的分法. ...

  5. 洛谷3320 SDOI2015寻宝游戏(set+dfs序)(反向迭代器的注意事项!)

    被\(STL\)坑害了一个晚上,真的菜的没救了啊. 准确的说是一个叫\(reverse\ iterator\)的东西,就是我们经常用的\(rbegin()\) 有一个非常重要的性质 在反向迭代器中,+ ...

  6. 洛谷 P1118 数字三角形游戏 Label:dfs

    题目描述 有这么一个游戏: 写出一个1-N的排列a[i],然后每次将相邻两个数相加,构成新的序列,再对新序列进行这样的操作,显然每次构成的序列都比上一次的序列长度少1,直到只剩下一个数字位置.下面是一 ...

  7. 洛谷刷题记录(python)【入门6】函数与结构体

    [入门6]函数与结构体https://www.luogu.com.cn/training/105#problems P5735 [深基7.例1]距离函数 import mathdef solve(a, ...

  8. 洛谷p1506——拯救oibh总部 Java题解 DFS

    看了一下java的题解比较少,来发表一下Java AC代码.用的是DFS,染色题型. import java.util.*; public class Main{static Scanner sc=n ...

  9. 洛谷:P1506 拯救oibh总部(DFS)

    题目背景 oibh总部突然被水淹没了!现在需要你的救援-- 题目描述 oibh被突来的洪水淹没了>.<还好oibh总部有在某些重要的地方起一些围墙,用号表示,而一个封闭的号区域洪水是进不去 ...

最新文章

  1. 混合高斯模型(Mixtures of Gaussians)和EM算法
  2. conn.execute的用法
  3. python 图表_新手向——制作web图表(基于Python和GooPyCharts)
  4. 深拷贝与浅拷贝Object.assign()
  5. centos安装php7编译
  6. 更改后缀为.dex文件为.odex文件 让你的程序瘦身 运行更稳定
  7. NYOJ 588 Money
  8. 如何选择tomcat版本
  9. Linux 所有版本内核源码下载
  10. Ardunio开发实例-光敏电阻光线强度检测
  11. 计算机械效率的公式四种,初级中学物理计算公式定律整编汇总.doc
  12. 硬件模拟大师_用机器人做咖啡,“智咖大师”这样升级新零售
  13. 出现无法解析的外部符号 LZ4_decompress_safe等问题
  14. 如何寻找数组中最大值与最小值(取双元素法)
  15. 张赐荣 | 浅谈 UIAutomation 自动化技术在读屏软件中的应用
  16. 今天心情好,给各位免费呈上200兆SVN代码服务器一枚,不谢!
  17. STM32L+BC20+MQTT连接阿里云传输温湿度数据并控制继电器
  18. 4月17日黑客攻击事件简讯
  19. 人民币中间价“四连涨”迫近6.6区间 创逾半年新高
  20. `QStyle`自定义重绘`QSlider`控件

热门文章

  1. python 聚类分析实战案例:K-means算法(原理源码)
  2. 江苏省10大IT培训机构排行榜
  3. 谈谈IT培训机构的骗局!
  4. 喜讯 | 地空智能荣获两项国家软件著作权证书
  5. Python爬虫基础入门(二)——列表
  6. python-装包与解包
  7. B2B电商交易系统:如何帮助智能照明企业实现精细化运营管理
  8. 项目管理之:CMMI规范风险管理(RSKM)
  9. 包工协议书样本_工程清包工合同协议书样本
  10. 函数 内置函数 动态数组 字符