Topcoder 12519 ScotlandYard(点对 dp+最长路)
题意:
有两个人 A 和 B 玩一个游戏。游戏规则大致是这样的:
有 \(n\) 个城市和三种交通工具公交、地铁和出租车。
给出三个 \(n\times n\) 的字符矩阵 \(b,m,t\),\(b_{i,j}='Y'\) 表示从城市 \(i\) 可以通过公交到达城市 \(j\),\(b_{i,j}='N'\) 表示从城市 \(i\) 不可以通过公交到达城市 \(j\)。\(m,t\) 同理。
现在 A 要选择一个起始城市 \(i\),但是 B 不知道这个城市的编号。小 A 每次可以通过某种交通工具到达另一个城市,并将乘坐的交通工具告诉 B。如果 B 猜出了小 A 当前所在的城市,或者小 B 动不了了,游戏结束。
A 的得分为 A 经过的边数。求 A 得分的最大值,如果游戏可能永远进行下去,输出 -1。
\(1 \leq n \leq 50\)
话说这题出现了两次呢。。。记得 CSP 前一周学校模拟赛某道题就是这个,结果昨天模拟赛又出现了一遍。。。今天终于见到这题的真面貌了(
记 \(S\) 为当前 A 当前可能位于的城市的集合。初始 \(S=\{1,2,\dots,n\}\)。
如果小 A 搭乘了交通工具 \(x\),那么 \(S\) 就变为:\(S\) 中的点集通过交通工具 \(x\) 能到达的点。
答案就是最多进行多少次操作后 \(S\) 中剩一个点。
很容易想到 \(2^n\) 的做法,对于集合之间的相互转化关系连边,跑最长路。
其实并不用把集合中每个点都表示出来。
只需要找到两个代表点 \((i,j)\),对这些点对连边跑最长路就行了。
这样点的个数就降到了 \(n^2\)。
至于 \(-1\) 的情况,就是判断对点对建立的图中有没有环,记忆化搜索/拓扑排序就可以了。
时间复杂度 \(n^4\),是道思维题(为啥就想不出来呢,wtcl)
#include <bits/stdc++.h>
using namespace std;
#define fi first
#define se second
#define fz(i,a,b) for(int i=a;i<=b;i++)
#define fd(i,a,b) for(int i=a;i>=b;i--)
#define ffe(it,v) for(__typeof(v.begin()) it=v.begin();it!=v.end();it++)
#define fill0(a) memset(a,0,sizeof(a))
#define fill1(a) memset(a,-1,sizeof(a))
#define fillbig(a) memset(a,63,sizeof(a))
#define pb push_back
#define ppb pop_back
#define mp make_pair
typedef pair<int,int> pii;
typedef long long ll;
const int MAXN=50+5;
int n,dp[MAXN][MAXN],vis[MAXN][MAXN];
bool s1[MAXN][MAXN],s2[MAXN][MAXN],s3[MAXN][MAXN];
int dfs(int x,int y){
if(x>y) swap(x,y);
if(x==y) return 0;
if(vis[x][y]) return 1e9;
if(~dp[x][y]) return dp[x][y];
vis[x][y]=1;dp[x][y]=0;
for(int i=1;i<=n;i++) for(int j=1;j<=n;j++){
if((s1[x][i]&&s1[y][j])||(s1[x][i]&&s1[x][j])||(s1[y][i]&&s1[y][j])||
(s2[x][i]&&s2[y][j])||(s2[x][i]&&s2[x][j])||(s2[y][i]&&s2[y][j])||
(s3[x][i]&&s3[y][j])||(s3[x][i]&&s3[x][j])||(s3[y][i]&&s3[y][j]))
dp[x][y]=max(dp[x][y],dfs(i,j)+1);
}
vis[x][y]=0;return dp[x][y];
}
class ScotlandYard{
public:
int maxMoves(vector<string> taxi,vector<string> bus,vector<string> metro){
n=taxi.size();
for(int i=0;i<n;i++) for(int j=0;j<n;j++) s1[i+1][j+1]=(taxi[i][j]=='Y');
for(int i=0;i<n;i++) for(int j=0;j<n;j++) s2[i+1][j+1]=(bus[i][j]=='Y');
for(int i=0;i<n;i++) for(int j=0;j<n;j++) s3[i+1][j+1]=(metro[i][j]=='Y');
int ans=0;memset(dp,-1,sizeof(dp));
for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) ans=max(ans,dfs(i,j));
if(ans>=1e9) return -1;return ans;
}
};
//ScotlandYard program;
//int main(){
// int n;scanf("%d",&n);
// vector<string> taxi,bus,metro;
// for(int i=1;i<=n;i++){string s;cin>>s;taxi.pb(s);}
// for(int i=1;i<=n;i++){string s;cin>>s;bus.pb(s);}
// for(int i=1;i<=n;i++){string s;cin>>s;metro.pb(s);}
// printf("%d\n",program.maxMoves(taxi,bus,metro));
// return 0;
//}
Topcoder 12519 ScotlandYard(点对 dp+最长路)的更多相关文章
- [USACO2003][poj2138]Travel Games(dp/最长路)
http://poj.org/problem?id=2138 题意:给你一些单词和初始单词,在初始单词的任意位置你可以加任意一个字母,使得这个新单词在给的单词中有所出现,然后在这样不断迭代下去,让你求 ...
- UVA11324 The Largest Clique (强连通缩点+DP最长路)
<题目链接> 题目大意: 给你一张有向图 G,求一个结点数最大的结点集,使得该结点集中的任意两个结点 u 和 v 满足:要么 u 可以达 v,要么 v 可以达 u(u,v相互可达也行). ...
- ZOJ 3795 Grouping (强连通缩点+DP最长路)
<题目链接> 题目大意: n个人,m条关系,每条关系a >= b,说明a,b之间是可比较的,如果还有b >= c,则说明b,c之间,a,c之间都是可以比较的.问至少需要多少个集 ...
- The Largest Clique UVA - 11324( 强连通分量 + dp最长路)
这题 我刚开始想的是 缩点后 求出入度和出度为0 的点 然后统计个数 用总个数 减去 然而 这样是不可以的 画个图就明白了... 如果 减去度为0的点 那么最后如果出现这样的情况是不可 ...
- UVA 103 Stacking Boxes 套箱子 DAG最长路 dp记忆化搜索
题意:给出几个多维的箱子,如果箱子的每一边都小于另一个箱子的对应边,那就称这个箱子小于另一个箱子,然后要求能够套出的最多的箱子. 要注意的是关系图的构建,对箱子的边排序,如果分别都小于另一个箱子就说明 ...
- ZOJ 3795:Grouping(缩点+最长路)
http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=5303 题意:有n个人m条边,每条边有一个u,v,代表u的年龄大于等于v,现在要 ...
- hdu 1025 dp 最长上升子序列
//Accepted 4372 KB 140 ms //dp 最长上升子序列 nlogn #include <cstdio> #include <cstring> #inclu ...
- poj1159 dp最长公共子串
//Accepted 204 KB 891 ms //dp最长公共子串 //dp[i][j]=max(dp[i-1][j],dp[i][j-1]) //dp[i][j]=max(dp[i][j],dp ...
- 中南大学oj 1317 Find the max Link 边权可以为负的树上最长路 树形dp 不能两遍dfs
http://acm.csu.edu.cn/OnlineJudge/problem.php?id=1317经典问题:树上最长路,边权可以为负值的,树形dp,不能用两边dfs.反例:5 41 2 22 ...
随机推荐
- better-scroll快速上手及封装(vue项目)
愿你有诗有梦,有坦荡荡的远方 本文声明:这是一篇学习coderwhy老师的vue2课程的一个笔记,所以本文章是在vue项目中实现,没学过vue的大佬们可以举一反三. 使用场景及介绍 BetterScr ...
- '\r'(回车符),'\n'(换行符)与"\r\n"
一.'\n','\r'和"\r\n" 回车\r本义是光标重新回到本行开头,r的英文return,控制字符可以写成CR,即Carriage Return(回车,carriage有&q ...
- Codeforces1575D
思路分析 此题采用dfs,注意X选中了之后所有的X值相同,所以需要一个flag来存储X的值. 注意前导0要单独讨论,然后就是当'X'或者'_'在第一位时不能选0,其它位可以选0 - 9 任意一个数. ...
- AIApe问答机器人Scrum Meeting 5.1
Scrum Meeting 5 日期:2021年5月1日 会议主要内容概述:汇报两日工作. 一.进度情况 组员 负责 两日内已完成的工作 后两日计划完成的工作 工作中遇到的困难 李明昕 后端 Task ...
- PCIE学习笔记--PCIe错误源详解(二)
转载地址:http://blog.chinaaet.com/justlxy/p/5100057799 这篇文章主要介绍事务(Transaction)错误.链路流量控制(Link Flow Contro ...
- 好好的 Tair 排行榜不用,非得自己写?20 行代码实现高性能排行榜
TairZset 是阿里云自研的可实现任意维度 double 类型的分值排序的数据结构,借助 Tair 客户端同时可实现扩展性,即可以将计算任务分布至多个数据节点完成,实现分布式排行榜能力.本文介绍了 ...
- 『学了就忘』Linux基础命令 — 31、grep命令和通配符
目录 1.grep命令介绍 2.find命令和grep命令的区别(重点) (1)find命令 (2)grep命令 3.通配符与正则表达式的区别 (1)通配符: (2)正则表达式: 1.grep命令介绍 ...
- LeetCode 重排链表 OPPO笔试
重排链表 几个关键点: 1. 双指针(快慢指针找中点)(用于反转后一部分) 2. 反转后一部分 (reverse函数) 3. 合并链表 合并的时候在笔试的时候想了一种比我之前想的简单的方法 从slow ...
- google浏览器设置检查元素显示框位置
- mysql批量修改某一列的值为另外的值
sql语句 UPDATE tb_info SET org_id = 2170 WHERE org_id = 815