http://acm.whu.edu.cn/land/problem/detail?problem_id=1546

这个题目还是聪哥教的方法过的

首先搜索是必须的,而且通过搜索来缩点,这些应该要想到,即把图上的起点和终点还有能量点进行标记,之后用bfs找到这些个点的最短路,最多只有12个点,这样对12个点进行状态压缩DP,状态压缩这部分不是很好写

用dp[i][j]表示在状态i的情况下,此刻在j点落脚的最大能量数,则先枚举i再枚举j,再枚举k,k代表已经存在于i里面的点 每次从dp[i][k]过度到dp[i][j],从dp[i][k]+dis[k][j]+dis[j][m+1]<=L(m+1是终点)则可以进行转移,取得该能量。

整个状态转移走完找出最大的能量数跟需求判断下即可得出结果

#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
#define INF 1<<30
using namespace std;
char g[][];
int vis[][];
int num[];
int d[][];
int dp[<<][];
int dis[<<][];
int w,h,l,m,s;
struct node
{
int x,y,deep;
} v[];
int dir[][]={{,},{,-},{,},{-,}};
void bfs(int x,int y)
{
node sx=node{x,y,};
queue<node> q;
q.push(sx);
memset(vis,,sizeof vis);
char cc=g[x][y];
while (!q.empty())
{
node nx=q.front();
q.pop();
if (vis[nx.x][nx.y]) continue;
vis[nx.x][nx.y]=;
for (int i=;i<;i++)
{
node qx=(node){nx.x+dir[i][],nx.y+dir[i][],nx.deep+};
if (qx.x< || qx.x>=h || qx.y< || qx.y>=w) continue;
if (vis[qx.x][qx.y]) continue;
char ch=g[qx.x][qx.y];
if (ch=='#') continue;
if (ch>='a' && ch<='a'+m+)
{
if (d[cc-'a'][ch-'a']>qx.deep)
d[cc-'a'][ch-'a']=qx.deep;
//cout<<cc-'a'<<" "<<ch-'a'<<" "<<d[cc-'a'][ch-'a']<<" aaa"<<endl;
}
q.push(qx);
}
}
}
int main()
{
int t;
scanf("%d",&t);
while (t--)
{
scanf("%d%d%d%d%d",&w,&h,&l,&m,&s);
for (int i=;i<=m;i++)
scanf("%d",&num[i]);
for (int i=;i<h;i++){
scanf("%s",g[i]);
}
int tmp=;
for (int i=;i<h;i++)
for (int j=;j<w;j++)
d[i][j]=INF;
for (int i=;i<h;i++)
{
for (int j=;j<w;j++)
{
if (g[i][j]=='$')
g[i][j]='a';
if (g[i][j]=='@')
g[i][j]='a'+(tmp++);
if (g[i][j]=='<')
g[i][j]='a'+m+;
}
}
for (int i=;i<=h;i++)
{
for (int j=;j<=w;j++)
{
if (g[i][j]>='a' && g[i][j]<='a'+m+){
// cout<<i<<" "<<j<<endl;
bfs(i,j);
//进行BFS缩点 //cout<<endl;
}
}
}
int ret=;

//对可以直接取得点先取了 for (int i=;i<=m;i++)
{
if (d[i][m+]<=l/)
{
ret+=num[i];
num[i]=;
}
}
int ans=;
memset(dp,-,sizeof dp);
memset(dis,,sizeof dis);
for (int i=;i<m;i++)
{
dis[<<i][i+]=d[][i+];
if (d[][i+]+d[i+][m+]<=l){
ans=max(ans,num[i+]);
dp[<<i][i+]=num[i+];
}
}
for (int i=;i<(<<m);i++)
{
for (int j=;j<=m;j++)
{
if (!(<<(j-) & i)) continue;
int tmp=i-(<<j-);
if (tmp==) continue;
int td=d[j][m+];
for (int k=;k<=m;k++)
{
if (dp[tmp][k]==-) continue;
if (!(tmp&(<<k-))) continue;
if (dis[tmp][k]+d[k][j]<=l-td)
{
if (dp[i][j]==-)
{
dp[i][j]=dp[tmp][k]+num[j];
dis[i][j]=dis[tmp][k]+d[k][j];
}
else
if (dp[i][j]<dp[tmp][k]+num[j])
{
dp[i][j]=dp[tmp][k]+num[j];
dis[i][j]=dis[tmp][k]+d[k][j];
}
}
}
ans=max(ans,dp[i][j]);
}
}
if (ret+ans<s || d[][m+]>l)
puts("NO");
else
puts("YES");
}
return ;
}

WOJ 1546 Maze 图论上的状态压缩DP的更多相关文章

  1. hdu 5094 Maze 状态压缩dp+广搜

    作者:jostree 转载请注明出处 http://www.cnblogs.com/jostree/p/4092176.html 题目链接:hdu 5094 Maze 状态压缩dp+广搜 使用广度优先 ...

  2. 旅行商问题——状态压缩DP

    问题简介 有n个城市,每个城市间均有道路,一个推销员要从某个城市出发,到其余的n-1个城市一次且仅且一次,然后回到再回到出发点.问销售员应如何经过这些城市是他所走的路线最短? 用图论的语言描述就是:给 ...

  3. hoj2662 状态压缩dp

    Pieces Assignment My Tags   (Edit)   Source : zhouguyue   Time limit : 1 sec   Memory limit : 64 M S ...

  4. POJ 3254 Corn Fields(状态压缩DP)

    Corn Fields Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 4739   Accepted: 2506 Descr ...

  5. [知识点]状态压缩DP

    // 此博文为迁移而来,写于2015年7月15日,不代表本人现在的观点与看法.原始地址:http://blog.sina.com.cn/s/blog_6022c4720102w6jf.html 1.前 ...

  6. HDU-4529 郑厂长系列故事——N骑士问题 状态压缩DP

    题意:给定一个合法的八皇后棋盘,现在给定1-10个骑士,问这些骑士不能够相互攻击的拜访方式有多少种. 分析:一开始想着搜索写,发现该题和八皇后不同,八皇后每一行只能够摆放一个棋子,因此搜索收敛的很快, ...

  7. DP大作战—状态压缩dp

    题目描述 阿姆斯特朗回旋加速式阿姆斯特朗炮是一种非常厉害的武器,这种武器可以毁灭自身同行同列两个单位范围内的所有其他单位(其实就是十字型),听起来比红警里面的法国巨炮可是厉害多了.现在,零崎要在地图上 ...

  8. BZOJ-1226 学校食堂Dining 状态压缩DP

    1226: [SDOI2009]学校食堂Dining Time Limit: 10 Sec Memory Limit: 259 MB Submit: 588 Solved: 360 [Submit][ ...

  9. HDU 1074 (状态压缩DP)

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=1074 题目大意:有N个作业(N<=15),每个作业需耗时,有一个截止期限.超期多少天就要扣多少 ...

随机推荐

  1. 谈谈函数式编程curry

    Curry概念 The concept is simple: You can call a function with fewer arguments than it expects. It retu ...

  2. win上java1.7和1.8版本修改环境变量无效.md

    网上找了很多办法都没用. 解决办法: 看看自己 "系统环境变量" 中是不是有 "C:\ProgramData\Oracle\Java\javapath" 这项配 ...

  3. 接口测试基础----postman、jmeter

    一,什么是接口 接口一般接口分两种: 系统对外接口:与外部系统对接的接口,用来获取或者传递数据给外部系统 系统内部接口:系统模块.方法之间用来获取或者传递数据的接口 二.接口分类 webservice ...

  4. PyPI提供双因素身份验证(2FA),已提高下载安全性

    前天,Python的核心开发团队宣布PyPI现在提供双因素身份验证(2FA),以提高Python包下载的安全性,从而降低未经授权的帐户访问的风险.该团队宣布将在Python Package Index ...

  5. Rails 第一课:环境配置 Ruby Rails RVM Heroku

    安装 上传专案到 Heroku 安装 Ruby 2.3.1 Rails 5.0.0.1 RVM 1.27.0 比较幸运一个问题都未碰到 MacOS 10.12.1 配置完成系统顺利升级到10.12.2 ...

  6. Kafka--Kafka简述

    Kafka的诞生 Kafka最初是LinkedIn的一个内部基础设施系统.我们发现,虽然有很多数据库和系统可以用来存储数据,但在我们的架构里,刚好缺一个可以帮助处理持续数据流的组件. 我们希望能够把数 ...

  7. C++面试常见问题——01预处理与宏定义

    C++面试常见问题--------01预编译和宏的使用 C++预处理器 预处理器是一些指令,它将指示编译器在实际编译之前需要完成的预处理.预处理必须要在对程序进行词法与语义分析.代码生成与优化等通常的 ...

  8. python 求两个数的最大公约数

    给定两个整数a,b,求他们的最大公约数 def gcd(a,b): if a<b: a,b=b,a while(a%b != 0): c = a%b a=b b=c return b a,b = ...

  9. 云时代架构阅读笔记二——Java性能优化(二)

    承接上文Java性能优化(一)https://www.cnblogs.com/guo-xu/p/11019267.html 4)尽量确定StringBuffer的容量 在说和这个标题相关之前,先说一下 ...

  10. 九十七、SAP中ALV事件之十,通过REUSE_ALV_COMMENTARY_WRITE函数来显示ALV的标题

    一.SE37查看REUSE_ALV_COMMENTARY_WRITE函数 二.查看一下导入 三.我们点击SLIS_T_LISTHEADER,来看一下类型 四.我们再看一下,这个info是60长度的字符 ...