poj Tony’s Tour (插头DP处女作--楼教主男(难)人八题之一)

扫码登录原理 扫码登录功能通过PC端与移动端的交互实现安全认证,分为三个阶段:待扫描阶段生成唯一二维码ID并轮询状态;已扫描阶段移动端提交token与二维码ID关联,生成临时token并要求用户确认;确认阶段验证临时token后为PC端生成正式登录凭证。整个过程通过二维码唯一性、状态轮询和二次确认机制确保安全性,防止未授权登录,最终完成跨设备认证流程。 阅读详情
/*
//题目链接:http://poj.org/problem?id=1739

acm记忆:在很久很久以前 ,当插头DP还只是被称作“基于连通性状态压缩动态规划”的时候,楼教主就将其化为男人八题 之列 !引得无数自认为很man的英雄豪杰欲AC之 而后快 !而吾等菜鸟是这学期才听闻 到还有插头DP一说 ,故欲快速刷之以解心中愁!遂捧着cdq(性别 :女)关于基于连通性状态压缩动态规划的论文研读数遍 ,别人一女生在论文里讲得貌似很简单,简单而我这个男生却看得 我神乎其神 !纠结数日不得解!思己既然 选择了做男人,那还是 要男人一会,所以不想去看这题 的解题报告,后放下 男人八题 ,在Timus的oj上 找到了需要用插头DP算法解决的 Formular1题,将各大神牛的代码结合 起来研读数日,终领会其精髓果断重拾 男人八题,可悲剧的是编码花了2小时,调试用 了哥哥一天的时间才AC,囧囧囧囧!在攻插头DP的过程中,多次都有认为自己 不像男人,但最终AC之后,才感觉重新做回了男人 !

 题目大意:在一个有阻碍点的矩阵里,从一个固定的点,到另一个固定点,将所以非阻碍点都遍历一遍的哈密顿通路的条数!
提示:DFS或BFS等搜索类方法,最坏的情况3的64次方,超时是必须的,所以不用想了!

此题难点是 :
1.关于每个点都有九个状态 ,要清晰地知道每个新状态的得到,应该对应于那几个原状态的!
2.换行的时候,最左边插头一定要等于0才能转移到下一行
3.还有就是此题和 Formular1不同的是,这题没有回路,所以“()“状态是不存在的(坑了我很久)!故此题只有8个状态!
4.最后就是:这里每个插头边有三种情况,所以用三进制的int型来表述每个插头的状态!

第一次接触此类题,所以代码的优化度不高!被我写了两百多行(貌似大神的也短不到哪儿去 ,嘿嘿) 废话不说那么多了,AC代码伺候 :
*/
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#define LL __int64
int hash[2][20005];
int state[2][20005];
LL dp[2][20005];
int  cnt[2];
int jz3[9];
inlineint get(ints, int pos)
{
 returns/jz3[pos]%3;
}
inlineint add(ints,int pos,int flag1,intflag2)
{
 returns+(flag1-s/jz3[pos]%3)*jz3[pos]+(flag2-s/jz3[pos+1]%3)*jz3[pos+1];
}
inlineint change(ints,int pos,int flag)
{
 returns+(flag-s/jz3[pos]%3)*jz3[pos];
}
inlinevoid  clear(intnow)
{
 memset(dp[now],0,sizeof(dp[now]));
 memset(hash[now],0,sizeof(hash[now]));
 cnt[now]=0;
}
int can(int s,intm)
{
 inti,flag,sum=0;
 for(i=0;i<=m;i++)
 {
  flag=s%3;
  s/=3;
  if(flag==1)sum++;
  if(flag==2)sum--;
  if(sum<0)break;
 }
 if(sum)return 0;
 elsereturn 1;
}
int main()
{
 intn,m,i,j,k,u,pre,now,col,raw,news,sum,mark,right;
 LL ans;
 charmap[9][9];
 for(jz3[0] = 1, i = 1; i < 9; i++) jz3[i] = jz3[i - 1] * 3;
 while(scanf("%d%d%c",&n,&m,&map[0][0])&&(m||n))
 {
  for(i = 1; i <= n; i++)
  {
   for(j = 1; j <= m; j++)
   {
    scanf("%c", &map[i][j]);
   }
   scanf("%c",&map[0][0]);
  }
  if(n==1||m==1)
   printf("0n");
  else
  {
   pre = 0, now = 1; clear(now),dp[now][0] = 1, cnt[now] = 1, state[now][cnt[now]] = 0, hash[now][0] = 1;
   for(i = 1; i <= n; i++)
   {
    for(pre = !pre, now = !now, clear(now), j = 1; j <= cnt[pre]; j++ )
    {
     if( (get(state[pre][j], m) == 0) &&((i==1)||state[pre][j])) 
     {
      news=state[pre][j] * 3;
      if(can(news,m))
      {
       state[now][++cnt[now]]=news;
       hash[now][news] = 1; 
       dp[now][news] = dp[pre][state[pre][j]];
      }
     }
    }
      
    for(j = 1;j <= m;j++)
    {
     pre = !pre, now = !now, clear(now);
     for(k = 1; k <= cnt[pre]; k++)
     {
      col = get(state[pre][k],j-1), raw = get(state[pre][k],j);
      if(map[i][j] =='#')
      {
       if(!(col||raw))
       {
        dp[now][state[pre][k]] += dp[pre][state[pre][k]];
        if(!hash[now][state[pre][k]]) state[now][++cnt[now]] = state[pre][k], hash[now][state[pre][k]] = 1;
       }
      }
      else
      {
       if(!(col||raw))
       {
        news = add(state[pre][k], j-1, 1, 2);
        if(can(news,m))
        {
         dp[now][news] += dp[pre][state[pre][k]];
         if(!hash[now][news]) state[now][++cnt[now]] = news, hash[now][news] = 1;
        }
       }
       elseif(col==0&&raw==1)
       {
        dp[now][state[pre][k]] += dp[pre][state[pre][k]];
        if(!hash[now][state[pre][k]]) state[now][++cnt[now]] = state[pre][k], hash[now][state[pre][k]] = 1;
        news = add(state[pre][k], j-1, 1, 0);
        if(can(news,m))
        {
         dp[now][news] += dp[pre][state[pre][k]];
         if(!hash[now][news]) state[now][++cnt[now]] = news, hash[now][news] = 1;
        }
       }
       elseif(col==1&&raw==0)
       {
        dp[now][state[pre][k]] += dp[pre][state[pre][k]];
        if(!hash[now][state[pre][k]]) state[now][++cnt[now]] = state[pre][k], hash[now][state[pre][k]] = 1;
        news = add(state[pre][k], j-1, 0, 1);
        if(can(news,m))
        {
         dp[now][news] += dp[pre][state[pre][k]];
         if(!hash[now][news]) state[now][++cnt[now]] = news, hash[now][news] = 1;
        }
       }
       elseif(col==0&&raw==2)
       {
        dp[now][state[pre][k]] += dp[pre][state[pre][k]];
        if(!hash[now][state[pre][k]]) state[now][++cnt[now]] = state[pre][k], hash[now][state[pre][k]] = 1;
        news = add(state[pre][k], j-1, 2, 0);
        if(can(news,m))
        {
         dp[now][news] += dp[pre][state[pre][k]];
         if(!hash[now][news]) state[now][++cnt[now]] = news, hash[now][news] = 1;
        }
       }
       elseif(col==2&&raw==0)
       {
        dp[now][state[pre][k]] += dp[pre][state[pre][k]];
        if(!hash[now][state[pre][k]]) state[now][++cnt[now]] = state[pre][k], hash[now][state[pre][k]] = 1;
        news = add(state[pre][k], j-1, 0, 2);
        if(can(news,m))
        {
         dp[now][news] += dp[pre][state[pre][k]];
         if(!hash[now][news]) state[now][++cnt[now]] = news, hash[now][news] = 1;
        }
       }
       elseif(col==2&&raw==1)
       {
        news = add(state[pre][k], j-1, 0, 0);
        if(can(news,m))
        {
         dp[now][news] += dp[pre][state[pre][k]];
         if(!hash[now][news]) state[now][++cnt[now]] = news, hash[now][news] = 1;
        }
       }
       elseif(col==1&&raw==1)
       {
        sum=1;
        for(u = j + 1; u <= m; u++)
        {
         mark = get(state[pre][k],u);//这里的参数u原本被写成j了,是我花了几个小时一个一个状态的调试出来的,之伤感!
         if(mark==1)sum++;
         if(mark==2)sum--;
         if(!sum)break;
        }
        if(!sum)
        {
         news = add(state[pre][k], j-1, 0, 0);
         news=change(news, u, 1);
         if(can(news,m))
         {
          dp[now][news] += dp[pre][state[pre][k]];
          if(!hash[now][news]) state[now][++cnt[now]] = news, hash[now][news] = 1;
         }
        }
       }
       elseif(col==2&&raw==2)
       {
        sum=1;
        for(u = j -2; u >= 0; u--)
        {
         mark = get(state[pre][k],u);
         if(mark==1)sum--;
         if(mark==2)sum++;
         if(!sum)break;
        }
        if(!sum)
        {
         news = add(state[pre][k], j-1, 0, 0);
         news=change(news, u, 2);
         if(can(news,m))
         {
          dp[now][news] += dp[pre][state[pre][k]];
          if(!hash[now][news]) state[now][++cnt[now]] = news, hash[now][news] = 1;
         }
        }
       }
     }
    }
   }
  }
  ans=0,right=jz3[0]+2*jz3[m-1];
  for(j = 1; j <= cnt[now]; j++)
  {
   if(state[now][j]==right)
    ans+=dp[now][state[now][j]];
  }
  printf("%I64dn",ans);
  }
 }
 return0;
}
/*
3 2
..
..
..
2 2
..
..
2 3
#..
...
3 4
....
....
....
*/

在 Eclipse 中接入 DeepSeek:开启 Java 开发新效率 DeepSeek 能够根据自然语言描述,精准生成高质量的 Java 代码片段。无论是简单的方法编写,比如 “编写一个 Java 方法,用于计算两个整数的乘积”,还是复杂的类和功能模块创建,例如 “创建一个 Java 类,实现文件的读写操作,并包含异常处理机制”,它都能快速给出合理且可运行的代码示例。DeepSeek 生成的代码不仅实现了基本功能,还遵循 Java 的编码规范,添加了必要的注释,让代码更易于理解和维护,大大节省了开发者从头编写代码的时间和精力。 阅读详情

相关推荐

多机器人协同:水下机器人集群的分布式控制与ROS仿真实践

本文探讨了多自主水下机器人(AUV)集群的分布式控制方法,重点分析了欠驱动6自由度AUV模型的反馈线性化技术。通过ROS/Gazebo仿真平台,详细介绍了系统架构设计、通信延迟补偿策略及环境扰动应对方案,为水下协同作业提供实用参考。

jupi8的博客 687

poj1740-楼教主所谓的男人八题之一

*题目大意: * 对于n堆石子,每堆若干个,两人轮流操作,每次操作分两步, * 第一步从某堆中去掉至少一个,第二步(可省略)把该堆剩余 * 石子的一部分分给其它的某些堆。最后谁无子可取即输。 *解题思路: * 1、先考虑1堆的时候,1堆当然是N点(必胜点), * 2、然后考虑2堆,细想一下可以发现,当2堆一样时,这个时候 * 的目的就是要把对方给逼到只有2堆都是1的时候,就能必胜了。

zhang20072844的专栏 5427

SUMO仿真教程(1) ——安装环境的设置(Windows 10系统)

SUMO安装环境的设置 目录一.SUMO下载的官方网址二.下载步骤:三.环境设置:1.打开设置环境变量的界面2.用户(Administrator)变量设置3.系统变量设置四.总述 一.SUMO下载的官方网址 sumo的下载地址: 二.下载步骤: 1.以sumo1.8.0为示例进行演示,点击下载地址; 2.选择Windows64位的安装版本,如下图所示: 3.点击对应版本会跳转到如下图所示的界面,等待几秒后会自动下载(温馨提示:请将下载路径提前设置好): 4.到目标存储路径下查看下载完成的SUMO(本

weixin_50632459的博客 1万+

男人八题系列

男人之路。。。还差最后一题,敬请期待~

Bright-XL 8219

VSCode配置C/C++语言环境(小白专用保姆教程)(超细)

VSCode配置C/C++语言环境(小白专用保姆教程)(超细)

ITQWQ的博客 8229

工业机器人抓取目标检测与抓取姿态估计系统:基于YOLOv12与Cornell Grasping Dataset

工业机器人抓取是自动化生产中的核心环节,而精确的目标检测和抓取姿态估计是实现高效抓取的关键。本文将详细介绍如何构建一个完整的工业机器人抓取系统,该系统结合了最新的YOLOv12目标检测算法和Cornell Grasping Dataset的抓取姿态估计,并提供了用户友好的UI界面。本文详细介绍了一个完整的工业机器人抓取系统,该系统结合了YOLOv12目标检测和基于Cornell Grasping Dataset的抓取姿态估计。我们将使用PyQt5构建一个用户友好的界面,集成目标检测和抓取姿态估计功能。

YOLO 574

POJ 1739 Tony's Tour (插头DP)

题目类型  插头DP 题目意思 给出  2^n 支足球队 (1 那么每轮对于没有淘汰的足球队每次从左往右选两支足球队进行比赛 例如第一轮的比赛的对阵情况肯定是这样的->  (0,1) (2,3) (4,5) (6, 7) 然后第二轮的对阵情况要根据第一轮的结果再进行配对 例如第一轮的胜者分别是 0 2 5 7的话第二轮的对阵情况就是 (0,2) (5,7)  依次这样最

yunyouxi0's blog 853

超级详细的GNS3最新版3-2.2.50安装配置教程,网工速度收藏!

你好,这里是网络技术联盟站,我是瑞哥。上周给大家分享了GNS3安装包。周末的时候有小伙伴在安装的时候遇到了一些问题,瑞哥周末特地从头安装了一下GNS3,今天给大家出个安装的教程,每一步的步骤我都截图了下来,希望对大家有所帮助!

网络技术联盟站 1109

POJ 1739 Tony's Tour 解题报告(插头DP)

楼教主男人八题之一,插头DP。可以直接用Ural1519的代码,将地图那块改下即可。如下图:     就是在原有的地图下方加入两行,求此图的哈密顿回路即可。     代码如下: #include #include #include using namespace std; #define LL long long const int maxn=10007; int m,

SF-_- 的 ACM 博客 1021

C语言试题四之计算并输出3到n之间所有素数的平方根之和

1、题目 请编写函数function,它的功能是:计算并输出3到n之间所有素数的平方根之和 例子:若我们main函数从键盘给n输入5之后,我们需要输出结果为3.968119 输入值n的要求:正整数n, 要求小于100。 2、部分函数说明 C 库函数 double sqrt(double x) 返回 x 的平方根 3、源代码实现 #include <stdio.h> #...

码莎拉蒂 7232

北斗导航 | 卫星/惯导组合导航方法

从组合导航结构方面来讲,卫星/惯导(下文以GPS/INS)组合模式一般分为三种,即松组合、紧组合和超紧组合(即深组合)。

尘世冰封的专栏 1536

POJ - 1739 Tony's Tour (单回路插头dp)

题目大意:给出一张图,要求从左下角走到右下角,且所有的非障碍点都走一次,问有多少种方法解题思路:在后面加上两行就可以当成单回路插头DP了 比如 … … .#. 后面加上两行后,就变成了饿 … … .#. .#. … 加的后面的两行只有一条路径#include<cstdio> #include<cstring> #include<algorithm> using namespac

静静地码 1013

Ollama DNS 重新绑定攻击 (CVE-2024-28224)

一旦 DNS 重新绑定攻击成功,攻击者就可以对这些 API 进行排序,以读取 Ollama 运行的进程可访问的任意文件数据,并将这些数据泄露到攻击者控制的系统中。完成对“创建模型” API 请求的调用后,Ollama 将收集组成新创建的用户模型的许多工件,包括大型语言模型数据、许可证数据等,以及我们要提取的文件,所有这些都可以通过其 SHA256 内容进行寻址。这是我们要窃取的文件,在我们的示例中,是可通过运行 Ollama 的主机上的路径名访问的现有文本文件。值得注意的是,该模型配置为通过参数中的。

技术超强的网络安全平台 1648

poj1739之插头DP

Tony's Tour Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 3256   Accepted: 1510 Description A square township has been divided up into n*m(n rows and m c

Stephen 1405

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

廖雪峰Python教程[完整版]

廖雪峰的python教程整理的,已经排好版了,而且还是完整的,适合小白

linux进程sleep硬盘,linux下线程调用sleep,进程挂起

【POJ】【1739】Tony&&num;39&semi;s Tour插头DP 楼教主男人八题之一! 要求从左下角走到右下角的哈密顿路径数量. 啊嘞,我只会求哈密顿回路啊……这可怎么搞…… 容易想到:要是把起点和重点直接连上就变成一条回路了……那么我们就连一下~ 我们可 ...Spring Data JPA教程&comma; 第二部分&colon; CRUD...

weixin_35403151的博客 163

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

hdu 4512 吉哥系列故事——完美队形I(最长上升公共子串)

求最长上升公共子串 f【i】【j】表示a(1,i),b(1,j)取以b【j】结尾的最大公共上升子串的大小 当a【i】 != b【j】 时,f【i】【j】 = f【i - 1】【j】 否则:f【i】【j】 = max { f【i - 1】【(1……j - 1)】 && (a[i] > b[1……j - 1])}; #include #include #include #define

SprintfWater的专栏 2681

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

hdu 4504威威猫系列故事——篮球梦

第五题:整数划分 dp[m] += dp[m - i](i = 1,2,3) #include #include #include #include using namespace std; #define INF 100000000 #define MAXN 200

SprintfWater的专栏 1955

hdu 4044 GeoDefense

//该题链接http://acm.hdu.edu.cn/showproblem.php?pid=4044 /* 报告人:SpringWater(GHQ)   //此题大意:一个以1为根节点的树,每个节点可以有修防御系统,每个节点的   防御系统(具有不同的价格和防御力)有chioce种可能的选择,敌人的基地为根节点,我方的基地为所有的叶   子节点,敌人可以随机发射一个攻击(具有一定的

SprintfWater的专栏 1914

成都区域赛区Maze杭电4035(dp求期望)

解题思路分析过程转载 : 02.    dp求期望的题。 03.    题意: 04.    有n个房间,由n-1条隧道连通起来,实际上就形成了一棵树, 05.    从结点1出发,开始走,在每个结点i都有3种可能: 06.        1.被杀死,回到结点1处(概率为ki) 07.        2.找到出口,走出迷宫 (概率为ei) 08.        3.和

SprintfWater的专栏 1811

hdu 2152 fire

/* 题目链接:http://poj.org/problem?id=2152   题意:城市树形分布,每个城市修建消防站的有一个花费值cost,且,当该地着火,离他最近的那个消防站必须小于   need,问要保证每个地方都能得到安全防护,需要的最小花费为?       解题思路:令dp[i][j]为,保护i点的消防站修建在j点且以i为根节点,所有孩子即自己都能得到保护的的最小花费

SprintfWater的专栏 1775

hdu 4405 Aeroplane chess(很水的期望DP)

题目大意:通过摇筛子,做0跳到n点,有些点可以直接过渡,问要到达n点,需要摇色子的次数的期望值? 状态转移方程: 首先dp【N】=0; 其次分两种情况: (1)i点不可以过渡,dp【i】=sum((dp【i+j】+1)/6) (2)i点可以过渡到j点,dp【i】=dp[j] 代码如下: #include #include #define MAXN 100005 int

SprintfWater的专栏 1591

hdu 4258(斜率优化DP)

题目大意:将n个升序数字序列,分成几组连续的序列 ,每一组的所得值,等于最右边的num2减去最左边 的num1,的平方+c即(numi-numj)^2+c 解题报告 人:GHQ(SpringWater) 分析可得:(dp[j2]-dp[j1]+num[j2+1]*num[j2+1]-num[j1+1]*num[j1+1])/(2(num[j2+1]-num[j1+1]))《=num[i

SprintfWater的专栏 1507

hdu 4519 郑厂长系列故事——体检(贪心)

比赛的时候,尼吗忘了N《=M的那种情况,害我wa了一次,忏悔! 见代码一目了然: #include #include int main() { int T, N, K, M; for(scanf("%d", &T); T--;) { scanf("%d%d%d", &N, &K, &M); if(N <= M) printf("%d\n", K); else printf("%d\n"

SprintfWater的专栏 1368

区间DP(可以看成记忆化搜索)

最少步 Time Limit : 3000/1000ms (Java/Other)   Memory Limit : 65535/32768K (Java/Other) Total Submission(s) : 22   Accepted Submission(s) : 4 Font: Times New Roman | Verdana | Georgia Font Size: ←

SprintfWater的专栏 1357

hdu 4412 Sky Soldiers(区间DP)

题目问题抽象之后为:在一个x坐标轴上有N个点,每个点上有一个概率值,可以修M个工作站,                      求怎样安排这M个工作站的位置,使得这N个点都走到工作站的距离期望值最小? 解题报告人:SpringWater(GHQ) 解题思路:状态方程:dp[i][j]  =  min{ dp[i - 1][k - 1]  + cost[k][j]   }dp[i][

SprintfWater的专栏 1206

zju Back to the Past 4624

//题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=4624 /*     题目来源:浙大十周年校赛第B题     题目类型:DP求期望值          结题报告人:SpringWater(GHQ)          题目大意:一个月光宝盒有两个面,每个面有n个洞,每个洞在晚上到来的时候就可能

SprintfWater的专栏 1109
下一篇: 上海区域赛Unlock the Cell Phone
SprintfWater
博客等级 码龄15年 242粉丝 139原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值