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 ...
随机推荐
- TreeSet和TreeMap中“相等”元素可能并不相等
TreeSet和TreeMap元素之间比较大小是借助Comparator对象的compare方法. 但有些时候,即便compare()返回0也不意味着这两个元素直观上相同. 比如元素是二元组[a,b] ...
- Java:抽象类和接口小记
Java:抽象类和接口小记 对 Java 中的 抽象类和接口,做一个微不足道的小小小小记 抽象类:使用 abstract 修饰,子类用 extends 继承: 接口:使用 interface 修饰,采 ...
- Unity 3D手游对不同分辨率屏幕的UI自适应
目前安卓手机的屏幕大小各异,没有统一的标准,因此用Unity 3D制作的手游需要做好对不同分辨率屏幕的UI自适应,否则就会出现UI大小不一和位置错位等问题. 我们的项目在开发时的参照分辨率(Refer ...
- BUAA 软工 | 从计算机技术中探索艺术之路
项目 内容 这个作业属于哪个课程 2020春季计算机学院软件工程(罗杰 任健) 这个作业的要求在哪里 第一次作业-热身! 我在这个课程的目标是 掌握软件开发方法学和工程学知识 这个作业在哪个具体方面帮 ...
- 【学习笔记】Vizing 定理
图染色问题的经典结论 定义 称一个边染色方案合法当且仅当每个顶点连出的所有边的颜色都互不相同,如果此时出现了 \(k\) 个颜色那么称该方案是图的一组 \(k\) 染色 一张无向图的边着色数为最小的 ...
- TensorFlow从入门到入坑(2)
TensorFlow学习(2) 一.jupyter notebook的安装和使用 1. 什么是jupyter notebook jupyter notebook(http://jupyter.org/ ...
- 『学了就忘』Linux基础 — 16、Linux系统与Windows系统的不同
目录 1.Linux严格区分大小写 2.Linux一切皆文件 3.Linux不靠扩展名区分文件类型 4.Linux中所有的存储设备都必须在挂载之后才能使用 5.Windows下的程序不能直接在Linu ...
- oracle 架构和一些工具了解
oracle的架构大概分为3部分, 客户端:用户端 oracle instance:叫做实例,由内存结构(内存池或者叫SGA)和后台进程组成.Oracle Instance是Oracle RDBMS的 ...
- 测试平台系列(72) 了解ApScheduler基本用法
大家好~我是米洛! 我正在从0到1打造一个开源的接口测试平台, 也在编写一套与之对应的完整教程,希望大家多多支持. 欢迎关注我的公众号测试开发坑货,获取最新文章教程! 回顾 上一节我们调研了一下市面上 ...
- adb 安装与使用(一)
一.ADB简介 1. 什么是adb? adb(Android Debug Bridage)是Android sdk的一个工具: adb 是用来连接安卓手机和PC端的桥梁,要有adb作为二者之间的维系, ...