UVALive-7354-Kitchen Measurements(BFS搜索)
来源:互联网 发布:mac双系统 没了一个 编辑:程序博客网 时间:2024/05/29 08:52
题目链接:点击打开链接
题目大意:
给定n(n<=5)个容积(v<=64)已知的杯子,体积从大到小,最开始最大的杯子是满的,给出最大体积杯子的目标状态,求:从初始状态到目标状态最少总共要倒多少单位体积的水。倒水的规则还是老规矩,总体积为每次倒水的体积和。
解题思路:
一:三个杯子的我们都写过,而这里最多有5个杯子,每个杯子的体积最大为64,用以前多维数组记录状态的方法就行不通了,然后我就GG了。
二:后面看了一下VJ上大佬们的代码,思路差不多是将每个状态进行hash,体积最多为64,那么将每一个状态hash成为一个65(64)进制的数,那么每个状态都可以唯一确定,不会有冲突,然后只要将hash,值解出来,就可以得到这个值对应的状态,看他们很多都用集合写的,然后我用queue()+map()TLE了(再一次Tmap)。
三:为什么要用map()?,因为对于一个状态hash()后,一个状态的hash值可以达到64^5级别,数组记录不了,而如果不这么hash的话又不好从hash值推出对应的状态。等等,既然这样,那么我们可以直接在每个结点都记录该节点对应的状态,然后只要保证一种不冲突而又可以用数组开下的hash方法就好了。不冲突,貌似进制数是能到的最简单的方法,但是上面提到了直接hash,数组开不下。其实再仔细想想,假如总共五个杯子,其中有四个杯子的状态已经确定了,那么最后一个杯子的状态也就确定了,该状态就是唯一确定的,而三个或者更少的就不能唯一确定状态,因为剩下的杯子的状态可以不唯一,所以我们可以只hash其中四个杯子,这样就只要开一个64^4级别的数组就可以记录状态了。
四:接下来就是正常的BFS()搜索了。
代码:
#include<iostream>#include<cstring>#include<string>#include<cstdio>#include<map>#include<queue>#include<set>#include<algorithm>#define LL long longusing namespace std;int n,k,v[10],pre[10];int mp[2*64*64*64*64+10];struct node{ int val[10]; int tot; int hash_val; bool operator < (const node &n1)const{ return tot>n1.tot; }}beg,in,out;int Hash(int a[]){ int sum=0; for(int i=0;i<n-1;i++){ sum=sum*65+a[i]; } return sum;}void _copy(int a[],int b[]){ for(int i=0;i<n;i++){ a[i]=b[i]; }}int BFS(){ priority_queue<node>Q; Q.push(beg); while(!Q.empty()){ int ok=0; out=Q.top();Q.pop(); _copy(v,out.val); if(v[0]==k)return out.tot; for(int x=0;x<n;x++){ for(int y=0;y<n;y++){ if(x==y)continue; if(!v[x]&&!v[y])continue; int tmp=min(v[x],pre[y]-v[y]); if(tmp==0)continue; v[x]-=tmp; v[y]+=tmp; int has=Hash(v); _copy(in.val,v); v[x]+=tmp; v[y]-=tmp; in.tot=out.tot+tmp; if(mp[has]!=0&&mp[has]<=in.tot)continue; mp[has]=in.tot; in.hash_val=has; Q.push(in); } } } return -1;}int main(){ // freopen("in.txt","r",stdin); while(~scanf("%d",&n)){ memset(mp,0,sizeof mp); memset(pre,0,sizeof pre); memset(v,0,sizeof v); for(int i=0;i<n;i++)scanf("%d",&pre[i]); v[0]=pre[0]; scanf("%d",&k); beg.tot=0;beg.hash_val=Hash(v); beg.val[0]=pre[0]; mp[beg.hash_val]=-1; int ans=BFS(); if(ans==-1)printf("impossible\n"); else printf("%d\n",ans); } return 0;}
哇!又是一道很涨姿势的搜索题啊,记得以前第一次写那个在迷宫取钥匙用二进制进行状态压缩,也是一脸懵比啊,这次来一个状态哈希(自己编的名字)?估计是水题刷多了,思维就比较局限了。
阅读全文
0 0
- UVALive-7354-Kitchen Measurements(BFS搜索)
- UVALive 6425 Intercity(bfs)
- UVALive 6658 - Fiasco(BFS)
- UVALive 3695 (博弈 bfs)
- 【BFS && 树】UVALive
- 搜索BFS
- 搜索 bfs
- 搜索 BFS
- BFS搜索
- UVALive 4877 记忆搜索
- UVALive - 2093 Moving Pegs bfs
- UVALive - 3977 Summits (BFS染色)
- UVALive 6930 Wheels(bfs)
- UVALive 4622 Decision(bfs)
- uvalive 6693 - Flow Game - BFS
- UVALive 7155 Keyboarding(BFS)
- UVALIVE 5893 计算几何+搜索
- UVALive 6255 Kingdoms --状态搜索
- 简单快捷的实现夜间模式
- 嵌入式linux平台设备驱动(设备驱动模型)开发之linux内核中的设备驱动
- Atitit 知识体系概论 attilax著 三大类型 学术型 应用型 职业技术教育1 附表1、CIP-2000学科群设置情况总表1 三大层次 分类 学科 专业2 20个知识大类2 需
- win7系统下载安装配置MySQL-5.7.19-winx64.zip
- 在Red Hat Enterprise Linux 7.0 x86_64下安装Oracle 11g R2
- UVALive-7354-Kitchen Measurements(BFS搜索)
- [BZOJ]4922: Karp-de-Chant Number DP
- One-bit DAC
- eclipse短信验证的布局
- Qt属性系统详解
- eclipse安装python插件(window环境)
- QT QGraphicsScene、QGraphicsItem、QGraphicsProxyWidget、QWidget间的事件传递
- Ubuntu安装配置串口通讯工具minicom&&cutecom
- HBase PerformanceEvaluation机制分析