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. 025、MySQL字符串大小写转化函数,文本转化大写,文本转化小写

    #变大写 SELECT UPPER('abcdABCD123a'); #ABCDABCD123A SELECT UCASE('abcdABCD123a'); #ABCDABCD123A #变小写 SE ...

  2. kali linux终端快捷键设置

    kali里面是没有终端快捷键的,需要自己设置. 打开设置->设备->keyboard,拉到最下面点击加号来新建一个快捷键. 名称:打开终端 命令:gnome-terminal 快捷键:Ct ...

  3. Codeforces1243C Tile Painting

    原题面:https://codeforces.com/contest/1243/problem/C 题目大意:给定数字n,有n个方块,第i个和第j个之间的距离(abs(i-j))如果是n的因子,那么第 ...

  4. 云服务器CentOS7系统环境配置(jdk和tomcat)

    配置jdk 下载与安装 如果没有安装wget,首先安装wget工具 yum -y install wget 安装完成后,在网上找到jdk的下载链接,可以在官网找点击此处到官网下载,如果官网下载慢也可以 ...

  5. springcloud微服务架构搭建入门笔记

    注册管理服务器 应用入口配置 @SpringBootApplication @EnableEurekaServer public class GatewayApplication { public s ...

  6. JS - input输入框点击回车提交或者进行别的操作

    $("input").keydown(function(event){ if (event.keyCode == 13) {         /* 提交或者别的操作 */ } }) ...

  7. cf 757C. Felicity is Coming!

    这个题还是比较劲的(题意太神了),才知道vector还可以==和排序,扒题解大法好!! #include<bits/stdc++.h> #define lowbit(x) x&(- ...

  8. JDBC面试知识点整理(温习用)

    要面试,所以把之前的笔记整理一遍,嘻嘻,加油 JDBC编程 使用JDBC,java程序可以轻松地操作各种主流数据库,Oracle,MySQL,等,使用JDBC编写的程序不仅可以实现跨数据库,还具有跨平 ...

  9. 094-PHP遍历索引数组和关联数组

    <?php $arr=array(63,'abc',45,'hello',3,7,9,'DEF'); //定义一个索引数组 echo '遍历一个索引数组:<br />'; forea ...

  10. 分享一个php加密字符串类。

    class base64{ /** * 加密字符串 * @access static * @param string $data 字符串 * @param string $key 加密key * @r ...