挖金子(1095)

题目描述

你在一个N*M的区域中,一开始在(1,1)的位置,每个位置有可能有金子,也有可能不能到达,也有可能有传送门。你只能往右或者下走,不能走出这个区域。当你位于传送门时,传送门你可以选择使用或者不使用,使用的次数无限,若使用则传送到传送门指定的位置。每个位置的金子你可以拿走它,问最后你最多能够拿走多少金子。

输入

首先测试数据组数T。

对于每组测试数据,先输入两个整数N,M(2<=N,M<=40)。

接下来是一个N*M的矩阵,表示每个位置的内容X,若0<=X<=9,表示该位置的金子个数为X,若X为'*',表示该位置有一个传送门,若X为'#',表示该位置不可到达。

假设传送门的个数为K个,接下来K行,每行两个整数x,y(0<=x<n,0<=y<m),依次表示每个传送门传送的位置,顺序是从第一行开始从上到下扫描,每一行从左往右扫描。

输出

对于每组数据,输出能够得到的最多的金子的个数。

样例输入

1
2 2
11
1*
0 0

样例输出

3

好累、- -

#include <iostream>
#include <cstdio>
#include <vector>
#include <cstring>
#include <algorithm>
using namespace std;
#define INF 0x3f3f3f3f
#define N 1610 int n,m;
int top;
int bcnt;
int Index;
int dfn[N];
int low[N];
int stack[N];
int belong[N];
bool instack[N];
vector<int> v1[N],v2[N]; int tn,k;
int dp[N];
int gold[N];
int mpt[][];
int num[][];
pair<int,int> p[N];
int dir[][]={,,,}; void init1()
{
k=tn=;
for(int i=;i<n*m;i++){
v1[i].clear();
v2[i].clear();
}
}
void init2()
{
top=-;
bcnt=Index=;
memset(dfn,,sizeof(dfn));
memset(low,,sizeof(low));
memset(instack,,sizeof(instack));
}
void tarjan(int u,int pre)
{
int son=,v;
dfn[u]=low[u]=++Index;
instack[u]=;
stack[++top]=u;
for(int i=;i<v1[u].size();i++){
v=v1[u][i];
if(!dfn[v]){
son++;
tarjan(v,u);
if(low[u]>low[v]) low[u]=low[v];
}
else if(instack[v] && low[u]>dfn[v])
low[u]=dfn[v];
}
if(dfn[u]==low[u]){
bcnt++;
do{
v=stack[top--];
instack[v]=;
belong[v]=bcnt;
}while(v!=u);
}
}
int dfs(int u)
{
if(dp[u]!=-) return dp[u];
dp[u]=gold[u];
for(int i=;i<v2[u].size();i++){
int v=v2[u][i];
dp[u]=max(dp[u],gold[u]+dfs(v));
}
return dp[u];
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
scanf("%d%d",&n,&m);
init1();
for(int i=;i<n;i++){ //编号
for(int j=;j<m;j++){
scanf(" %c",&mpt[i][j]);
if(mpt[i][j]!='#') num[i][j]=tn++;
if(mpt[i][j]=='*') p[k++]=make_pair(i,j);
}
}
for(int i=;i<k;i++){ //建图1
int tx,ty;
scanf("%d%d",&tx,&ty);
v1[num[p[i].first][p[i].second]].push_back(num[tx][ty]);
}
for(int i=;i<n;i++){ //建图2
for(int j=;j<m;j++){
if(mpt[i][j]=='#') continue;
for(int k=;k<;k++){
int tx=i+dir[k][];
int ty=j+dir[k][];
if(tx>= && tx<n && ty>= && ty<m && mpt[tx][ty]!='#')
v1[num[i][j]].push_back(num[tx][ty]);
}
}
}
init2();
for(int i=;i<tn;i++){ //Tarjan
if(!dfn[i]) tarjan(i,i);
}
memset(gold,,sizeof(gold));
for(int i=;i<n;i++){ //计算金币
for(int j=;j<m;j++){
if(mpt[i][j]>='' && mpt[i][j]<='') gold[belong[num[i][j]]]+=mpt[i][j]-'';
}
}
for(int i=;i<tn;i++){ //缩点建图
for(int j=;j<v1[i].size();j++){
if(belong[i]!=belong[v1[i][j]])
v2[belong[i]].push_back(belong[v1[i][j]]);
}
}
memset(dp,-,sizeof(dp));
int ans=dfs(belong[]); //记忆化搜索
printf("%d\n",ans);
}
return ;
}

[swustoj 1095] 挖金子的更多相关文章

  1. Dynamic Programming [Algorithm]

    今天学习动态规划01背包问题,从一篇非常不错的文章中学习甚多.转载于此,感谢作者的分享! 原文地址 通过金矿模型介绍动态规划 对于动态规划,每个刚接触的人都需要一段时间来理解,特别是第一次接触的时候总 ...

  2. 微信小程序 教程及示例

    作者:初雪链接:https://www.zhihu.com/question/50907897/answer/128494332来源:知乎著作权归作者所有,转载请联系作者获得授权.微信小程序正式公测, ...

  3. 西南科技大学第十届ACM程序设计竞赛题解

    A.德州扑克 B. 我恨11(1089) 问题描述 11是一个孤独的数字,小明十分讨厌这个数字,因此如果哪个数字中出现了11或者该数字是11的倍数,他同样讨厌这个数字.现在问题来了,在闭区间[L,R] ...

  4. 天草(初级+中级+高级)VIP和黑鹰VIP破解教程(全部iso下载地址)

    以下就是我收集的教程地址,之前我收集到的都是一课一课下载的,虽然这样,我也下载完了天草的全部课程.这里分享的是在一起的iso文件,比起一课课下载爽多了.~~ 还有这些教程都是从零起点开始教的,不用担心 ...

  5. 微信小程序资料集合

    一:官方地址集合: 1:官方工具:https://mp.weixin.qq.com/debug/wxadoc/dev/devtools/download.html?t=1476434678461 2: ...

  6. 「前端开发者」如何把握住「微信小程序」这波红利?

    由于前两周一直在老家处理重要事情,虽然朋友圈被「微信小程序」刷爆了,但并没有时间深入了解. 昨天回广州之后,第一件事情就是把「微信小程序」相关的文章.开发文档.设计规范全部看了一遍,基本上明白了「微信 ...

  7. 零基础数据分析与挖掘R语言实战课程(R语言)

    随着大数据在各行业的落地生根和蓬勃发展,能从数据中挖金子的数据分析人员越来越宝贝,于是很多的程序员都想转行到数据分析, 挖掘技术哪家强?当然是R语言了,R语言的火热程度,从TIOBE上编程语言排名情况 ...

  8. dynamic programming 学习

    这是看到一位大神,写的关于dynamic programming的博客,认为很好.简单分析下.然后给出链接. 背景问题就是 有一个国家,全部的国民都很老实憨厚,某天他们在自己的国家发现了十座金矿.而且 ...

  9. 近期热门微信小程序demo源码下载汇总

    近期微信小程序demo源码下载汇总,乃小程序学习分析必备素材!点击标题即可下载: 即速应用首发!原创!电商商场Demo 优质微信小程序推荐 -秀人美女图 图片下载.滑动翻页 微信小程序 - 新词 GE ...

随机推荐

  1. phpcms v9 打开网站特别慢 增加数据库缓存方法

    SET GLOBAL QUERY_CACHE_SIZE=80000000; 设置好查询缓存的大小就行了.比如设置个20MB.SET GLOBAL QUERY_CACHE_SIZE=20000000; ...

  2. 在制作joomla模板过程中遇到的问题

    '''问题1.'''在jjc首页中两个通知公告和基建首页的两个模块中,当我点击查看文章标题是,而通知公告和最新动态页一直都还显示,发现文章一直在网站的下部,而不显示在它应该显示的main_rigth模 ...

  3. c语言文件操作函数详解

    一.文件操作注意点: 1 打开文件时,如果打开方式加“+”,表示该文件可以“写” ; 2 退出程序一般用exit函数,正常退出参数为0,非正常退出参数为正零值 ; 3 文件的读写操作:按字符.字符串. ...

  4. javascript看你能够做对几题

    http://ourjs.com/detail/52fb82e13bd19c4814000001

  5. Eclipse开发Android报错Jar mismatch! Fix your dependencies

    常常打开工程,发现项目并没有错,但是会有一个红X,然后就生成不了. 发现两个版本不同的android-support-v4.jar在使用 打开window-show views-problems Ja ...

  6. XML文件序列化和反序列化的相关内容

    问题缘由: XML反序列化出错,XML 文档(2, 2)中有错误,不应有 <configuration xmlns=''> 解决方法: 其实这个是很简单的,因为一般来说都是XML文档书写错 ...

  7. MYSQL系列1_MySQL的安装,可视化工具的使用,以及建库建表等

    大家都知道MYSQL是开源的数据库,现在MYSQL在企业中的使用也越来越多,本人之前用过SQL SERVER数据库,因业务需要和自己的兴趣想要学习MYSQL,对于MYSQL,本人还是新手,请大家多多指 ...

  8. [转载]iOS本地推送-备用

    第一步:创建本地推送// 创建一个本地推送UILocalNotification *notification = [[[UILocalNotification alloc] init] autorel ...

  9. UILabel 根据内容的多少来计算label的frame

    self.label.text = @"...."; 计算 frame 的最新方法 //1.设置lable最大显示行数 self.label.numberOfLines = 0; ...

  10. [转载]WCF序列化65536大小限制的问题

    错误: The formatter threw an exception while trying to deserialize the message: There was an error whi ...