/* 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4026
 题目来源:上海区域赛Unlock the Cell Phone
报告人:SpringWater
题目类型:状态压缩
题目大意为:在一个存在跨越点和坏死点和正常点的矩阵中,求出遍历所有正常点且仅一次的哈密顿通路的数量总数 思路:这跟哈密顿图的解法差不多,其实就是求哈密顿通路个数吧。DP[i][s], 表示以结点i为最后一个连接点路径状态为s时的图像个数。转移式为DP[i][s] = DP[1][s ^ (1 << i)] + DP[2][s ^ (1 << i)] + ...DP[n][s ^ (1 << i)]。最后所有的DP[k][(1 << n + 1) - 1]求和为解。

解题感悟:此题是一个状态压缩类型的题,这类题型一般属于较难题,因为他不仅设计到图论的知识,还涵盖了数 论和数学建模的理论,以前从没做过类似的题目,所以这题的解题思路基本都是借鉴了别人的解题报告, 本想将他 处理没状态可达的方法优化一下的,即:我不罗列所有中间序号的点,而是从正常点向八个方向扩展, 但是后来发现虽然时间复杂度虽然有改观,但是编程复杂度 就大大加强了,所以 除了判断可达那里我做了 一些空间上的优化以外 其他的都没怎么改动,因为感觉别人的代码确实很精致美妙,!

通过这初次对状态压缩,感觉它是一个非常实用的思想,并且是很灵活,比起纯的dp要难与理解很多,因为关 键它涉及了很多二进制数论的运用!使得学起来比较吃力,但是我相信通过长时间多的磨练我会把它拿下的!目 前接算是对二维的状态压缩给解决了,接下来就深入到三维的状态压缩,尽管可能会有点难! */

#include<stdio.h>
#include<string.h>
int G[30],ordinary[17];
int SA[17][17],Hash[30];
__int64dp[17][1<<17];
int n,m,label;
int inputdata()//录入数据
{inti,j=n*m;for(i=0;i<j;i++){scanf("%d",&G[i]);if(!G[i]){Hash[i]=label;     ///用于快速找出当前被接入点的状态位置ordinary[label++]=i;///用于后面将两个点中间的所有点罗列出来}}return0;
}
int online(int x1,inty1,int x2,int y2,intmidx,int midy)
{return(y1-midy)*(x2-midx)==(y2-midy)*(x1-midx);    //判断三点是否构成一条直线
}
int prepare()
{int i,j,k,x1,y1,x2,y2,midx,midy;memset(SA,0,sizeof(SA));for(i=0;i<label-1;i++)for(j=i+1;j<label;j++){x1=ordinary[i]%m;y1=ordinary[i]/m;x2=ordinary[j]%m;y2=ordinary[j]/m;for(k=ordinary[i]+1;k<ordinary[j];k++){midx=k%m;midy=k/m;if(G[k]==1||!G[k]){if(online(x1,y1,x2,y2,midx,midy)){if(G[k]==1)//被坏死点阻隔{SA[i][j]=SA[j][i]=-1;break;}if((G[k]==0))//将所有的中间正常点记录下来{SA[i][j] |= (1<<Hash[k]);SA[j][i] |= (1<<Hash[k]);}}}}}return0;
}
int canreach(int i,int j,ints)//判断i,j点在当前s状态能否可达
{if(SA[i][j]==-1)return0;if(!SA[i][j])return1;returnSA[i][j]==(SA[i][j]&s);
}
int work()
{intsum=1<<label;inti,j,k;for(i=1;i<sum;i++){for(j=0;j<label;j++){if(i==1<<j)//当前状态是第一次接入点{dp[j][i]=1;continue;}else    dp[j][i]=0;if(i&(1<<j)){for(k=0;k<label;k++)//罗列出当前点j可能接入的所有入口点k{if((k!=j)&&(i&(1<<k))&&canreach(j,k,i))dp[j][i]+=dp[k][i-(1<<j)];}}}}return0;
}
int main()
{intsum,i;__int64ans;while(scanf("%d%d",&n,&m)!=EOF){label=0;inputdata();prepare();work();ans=0;sum=(1<<label)-1;for(i=0;i<label;i++)//将所有接入点的最后都接入的状态累加起来ans+=dp[i][sum];printf("%I64dn",ans);}return0;
}

上海区域赛Unlock the Cell Phone相关推荐

  1. HDU 3220 Alice’s Cube (09年上海区域赛水题(位压缩、逆向搜索、打表))

    这道题是09年上海区域赛的A题,虽然很水,但是不能直接爆搜,直接爆搜要T.于是我们看到题目的要求是说当操作的步数大于3的时候就输出more,那么我们可以从终态枚举进行了三次操作所能达到的所有状态,这个 ...

  2. 2021ICPC上海区域赛DEGKI

    题目链接: https://codeforces.com/gym/103446 视频讲解: https://www.bilibili.com/video/bv1994y1f76o 代码:https:/ ...

  3. 2019ICPC上海区域赛 补题(12/13) 总结

    前言: 个人的 ICPCICPCICPC 第一站,还是值得记录一下的(虽然咕到现在才记录),总体而言体验很不错,比赛兼旅游.这套题总体印象就是树树树图,作为队里数据结构兼图论选手,这次也确实写了大部分 ...

  4. 2020ICPC上海区域赛总结

    怎么说呢 想过打铁 但没想到真打铁了其实挺难受的 开局十分钟我交了第一发签到题,由于特判没有return0return 0return0白给了一发,加上之后又马上冲了一发结果还是WA了,这时我就一直在 ...

  5. 2019icpc上海区域赛(部分题解)

    B Prefix Code K Color Graph H Tree Partition D Spanning Tree Removal E Cave Escape F A Simple Proble ...

  6. 树形DP+并查集+左偏树, HDU-5575,Discover Water Tank,2015上海现场赛D题

    只是ACM/IICPC 2015 上海区域赛的一道题.原题链接:http://acm.hdu.edu.cn/showproblem.php?pid=5575 题目描述 N-1个木板把一个水箱划分成了N ...

  7. 2020年 ICPC 亚洲区域赛(上海)G-Fibonacci

    ICPC 亚洲区域赛(上海) G-Fibonacci 题目 斐波那契数列为1,1,2,3,5,8,13,21,- 可以看到,这个数列有以下特点: 奇,奇,偶,奇,奇,偶- 当 xxx 与 yyy 相乘 ...

  8. 2013长春区域赛总结

    今年因为参加了一场日本的区域赛,国内的区域赛只有一次机会.选择了来最后一个赛区长春,一方面准备时间比较充裕,另一方面也想弥补上年在长春留下的遗憾.长春是我的最后一场区域赛了,本来想着拿个金牌退役的,万 ...

  9. 2018ACM-ICPC国际大学生程序设计竞赛亚洲区域赛(青岛站)赛后总结

    这是今年最后一次打铁,我已经打了一年的铁了. 还是想写一个总结,不然,什么都会没留下. 实际上在去青岛之前,我已经一个月都没有严格地训练自己了,从9月份CCPC秦皇岛站打铁之后,我就基本上开始怀疑自己 ...

最新文章

  1. Java核心类库-IO-字节数组流/内存流
  2. static 函数和普通函数
  3. H3C S3600-EI 系列以太网交换机
  4. 通用技术和信息技术合格考知识点_高二信息与通用技术会考知识点
  5. matlab创建nc文件怎么打开,MATLAB打开nc文件并读取nc文件数据
  6. 鸿蒙系统非手机用,【图片】华为鸿蒙系统的厉害之处在于 你可能非用不可 !【手机吧】_百度贴吧...
  7. python,web框架说明
  8. 曼昆:宏观经济学简史(转)
  9. Java中的sql语句代码拼接问题
  10. 微信小程序 js部分语法
  11. python 下载安装 教程
  12. PyTorch YOLOV3 模型转换问题
  13. 小程序未来移动社交电商!
  14. android调用摄像头录像的代码(录像并生成mp4文件)
  15. java 刽子手图像代码,刽子手游戏代码
  16. 关于浏览器打开时自动打开部分网页(浏览器被劫持)的解决办法
  17. 关于视频的YUV格式介绍
  18. 阿里大鱼:自自定短信模板
  19. [mysql]存储过程/存储函数
  20. java实现mysql自动更新创建时间与更新时间的两种方式

热门文章

  1. 计算机考研自我介绍大概多少字,1分钟自我介绍大概多少字
  2. c语言最新标准c22,【C语言实例】c22-选择分支结构.doc
  3. 图形学篇:多边形有效边表填充算法
  4. Faceboxes pytorch代码解读(一) box_utils.py(上篇)
  5. 路由器linux+开机启动,路由器里设置FRP开机启动教程
  6. 一文掌握多分类logistic回归
  7. c语言lzma算法,在C中使用C-LZMA-SDK解压缩LZMA返回SZ_ERROR_DATA,因为输入流的第一个字节是!= 0...
  8. golang中channel的传递
  9. Spring Boot配置Tomcat容器、Jetty容器、Undertow容器
  10. 23、使用OpenCV和NCNN进行人物抠图并将背景设置成透明色