HDU--4784 Dinner Coming Soon DP+BFS
题意非常长非常变态。一个人要到他男朋友家,他最初有R元以及T分钟的时间来赶到他男朋友家。有N个房子M条道路,每条道路有须要消耗的时间以及过路费,同一时候还要顺路做食盐生意,起初身上没有食盐,最多带B袋盐,每到达一个地方有三种操作能够选择:1.售出一袋食盐;2:购买一袋食盐;3:什么都不做。然后你以为结束了?不!它还存在平行宇宙,在一个城市能够选择穿越平行宇宙到达还有一个宇宙的这个城市,不同宇宙的食盐价格不同可是过路费和道路须要的时间是同样的,并且因为他是穿越党,他不能在别的宇宙回到自己家或者男朋友家,求最后是否能到达他男朋友家以及最多能有多少钱。
BFS+DP,由于时间是不可逆的,所以每次依照时间的先后来处理状态,因此须要用优先队列来处理。
#include <iostream>
#include <cstdio>
#include <cmath>
#include <queue>
#include <algorithm>
#include <cstdlib>
#include <vector>
#include <iomanip>
#include <set>
using namespace std;
typedef long long ll;
const int maxn=111;
const int maxm=222;
struct Edge//邻接表
{
int v;
int tim;//时间花费
int cost;//金钱花费
int next;
};
struct Node
{
int u,times,k,b;
bool operator < (const Node &a) const
{
return times>a.times;
}
};
Edge edges[maxm<<1];
int head[maxn];
int num=-1;;
int n,m,B,K,R,T;
int dp[maxn][210][7][7];
int inqueue[maxn][210][7][7];
int price[7][maxn];
void addEdge(int u,int v,int tim,int cost)
{
num++;
edges[num].v=v;
edges[num].tim=tim;
edges[num].cost=cost;
edges[num].next=head[u];
head[u]=num;
}
int bfs()
{
int flag=0;
memset(dp,0,sizeof(dp));
memset(inqueue,0,sizeof(inqueue));
dp[1][0][0][0]=R;//初始金钱
Node node,tmp;
priority_queue<Node>q;//优先队列,按时间处理
node.u=1;//起始状态
node.times=0;
node.k=0;
node.b=0;
inqueue[1][0][0][0]=1;
q.push(node);
while(!q.empty())
{
node=q.top();
q.pop();
if(node.times>T)//当队里的元素的时间都大于T就无需处理了
{
break;
}
int u=node.u;
if(u==n)
{
//cout<<node.times<<endl;
continue;
}
for(int i=head[u];i!=-1;i=edges[i].next)//走到下一个城市
{
int v=edges[i].v;
int cost,tim;
cost=dp[u][node.times][node.k][node.b]-edges[i].cost;//剩下的金钱
tim=node.times+edges[i].tim;//时间
if(tim>T||cost<0)//剪枝
{
continue;
}
if(v==n&&node.k!=0)//仅仅能在0宇宙到达第N个城市
{
continue;
}
if(v==n)//成功到达
{
flag=1;
}
tmp.u=v;
tmp.times=tim;
tmp.k=node.k;
if(u!=1&&u!=n)
{
if(node.b+1<=B&&cost-price[node.k][u]>dp[v][tim][node.k][node.b+1])//买一袋盐
{
dp[v][tim][node.k][node.b+1]=cost-price[node.k][u];
tmp.b=node.b+1;
if(!inqueue[tmp.u][tmp.times][tmp.k][tmp.b])
{
q.push(tmp);
inqueue[tmp.u][tmp.times][tmp.k][tmp.b]=1;
}
}
if(node.b>0&&cost+price[node.k][u]>dp[v][tim][node.k][node.b-1])//卖一袋盐
{
dp[v][tim][node.k][node.b-1]=cost+price[node.k][u];
tmp.b=node.b-1;
if(!inqueue[tmp.u][tmp.times][tmp.k][tmp.b])
{
q.push(tmp);
inqueue[tmp.u][tmp.times][tmp.k][tmp.b]=1;
}
}
}
if(cost>dp[v][tim][node.k][node.b])//不买盐
{
dp[v][tim][node.k][node.b]=cost;
tmp.b=node.b;
if(!inqueue[tmp.u][tmp.times][tmp.k][tmp.b])
{
q.push(tmp);
inqueue[tmp.u][tmp.times][tmp.k][tmp.b]=1;
}
}
}
if(u!=1&&u!=n)//穿越到下一个宇宙的这个城市
{
int cost=dp[u][node.times][node.k][node.b];//金钱不变
tmp.u=u;
tmp.k=(node.k+1)%K;
tmp.times=node.times+1;//看广告时间+1
if(tmp.times>T)
{
continue;
}
if(node.b+1<=B&&cost-price[node.k][u]>dp[u][tmp.times][tmp.k][node.b+1])//在这个宇宙的这个城市买盐
{
dp[u][tmp.times][tmp.k][node.b+1]=cost-price[node.k][u];
tmp.b=node.b+1;
if(!inqueue[tmp.u][tmp.times][tmp.k][tmp.b])
{
q.push(tmp);
inqueue[tmp.u][tmp.times][tmp.k][tmp.b]=1;
}
}
if(node.b>0&&cost+price[node.k][u]>dp[u][tmp.times][tmp.k][node.b-1])//卖一袋盐
{
dp[u][tmp.times][tmp.k][node.b-1]=cost+price[node.k][u];
tmp.b=node.b-1;
if(!inqueue[tmp.u][tmp.times][tmp.k][tmp.b])
{
q.push(tmp);
inqueue[tmp.u][tmp.times][tmp.k][tmp.b]=1;
}
}
tmp.b=node.b;
if(cost>dp[u][tmp.times][tmp.k][tmp.b])//不做操作
{
dp[u][tmp.times][tmp.k][tmp.b]=cost;
if(!inqueue[tmp.u][tmp.times][tmp.k][tmp.b])
{
q.push(tmp);
inqueue[tmp.u][tmp.times][tmp.k][tmp.b]=1;
}
}
}
}
if(!flag)
{
return -1;//不能到达
}
int ans=0;
for(int i=0;i<=T;i++)
{
for(int j=0;j<=B;j++)
{
ans=max(ans,dp[n][i][0][j]);//能够到达,在能够到的的情况中选取钱最多的
}
}
return ans;
}
int main()
{
int t;
int s=1;
int u,v,tim,cost;
scanf("%d",&t);
while(t--)
{
scanf("%d%d%d%d%d%d",&n,&m,&B,&K,&R,&T);//城市数目,道路数目,食盐上限,宇宙个数,初始金钱,时间上限
memset(head,-1,sizeof(head));
num=-1;
for(int i=0;i<K;i++)
{
for(int j=1;j<=n;j++)
{
scanf("%d",&price[i][j]);//食盐在每一个宇宙每一个城市的价格
}
}
for(int i=0;i<m;i++)
{
scanf("%d%d%d%d",&u,&v,&tim,&cost);//每条路的起点,终点,时间,花费
addEdge(u,v,tim,cost);
}
int ans;
ans=bfs();
printf("Case #%d: ",s++);
if(ans!=-1)
{
printf("%d\n",ans);
}
else
{
printf("Forever Alone\n");
}
}
return 0;
}
HDU--4784 Dinner Coming Soon DP+BFS的更多相关文章
- hdu 4784 Dinner Coming Soon(spfa + 优先队列)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4784 思路:建图,对于同一个universe来说,就按题目给的条件相连,对于相邻的universe,连 ...
- HDU 3001 Travelling (状压DP + BFS)
题意:有一个人要去旅游,他想要逛遍所有的城市,但是同一个城市又不想逛超过2次.现在给出城市之间的来往路费,他可以选择任意一个点为起点. 问逛遍所有城市的最低路费是多少. 析:用三进制表示每个城市的访问 ...
- hdu 4784 Dinner Coming Soon
spfa+优先队列.刚开始只用的spfa,结果tle到死.然后听队友说要用到优先队列,想了想,对时间分层的话的确每一个结点都只进队列一次即可,因为只有大时间才能更新出小时间,然后就wa成shi了.按队 ...
- hdu 3247 AC自动+状压dp+bfs处理
Resource Archiver Time Limit: 20000/10000 MS (Java/Others) Memory Limit: 100000/100000 K (Java/Ot ...
- HDU 1003 Max Sum --- 经典DP
HDU 1003 相关链接 HDU 1231题解 题目大意:给定序列个数n及n个数,求该序列的最大连续子序列的和,要求输出最大连续子序列的和以及子序列的首位位置 解题思路:经典DP,可以定义 ...
- hdu 5094 Maze 状态压缩dp+广搜
作者:jostree 转载请注明出处 http://www.cnblogs.com/jostree/p/4092176.html 题目链接:hdu 5094 Maze 状态压缩dp+广搜 使用广度优先 ...
- hdu 3681 Prison Break(状态压缩+bfs)
Problem Description Rompire . Now it’s time to escape, but Micheal# needs an optimal plan and he con ...
- hdu 2829 Lawrence(斜率优化DP)
题目链接:hdu 2829 Lawrence 题意: 在一条直线型的铁路上,每个站点有各自的权重num[i],每一段铁路(边)的权重(题目上说是战略价值什么的好像)是能经过这条边的所有站点的乘积之和. ...
- hdu 4568 Hunter 最短路+dp
Hunter Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Subm ...
随机推荐
- python实现websocket服务器,可以在web实时显示远程服务器日志
一.开始的话 使用python简单的实现websocket服务器,可以在浏览器上实时显示远程服务器的日志信息. 之前做了一个web版的发布系统,但没实现在线看日志,每次发布版本后,都需要登录到服务器上 ...
- cpio.gz 解压
linux下cpio.gz文件的解压方法:今天下载了 10201_database_linux_x86_64.cpio.gz 文件,解压方法如下:1. gunzip 10201_database_li ...
- JavaScript中函数参数的按值传递与按引用传递(即按地址传递)
首先声明一句:JavaScript中所有函数的参数都是按值传递的!不存在按引用传递! 在讲传递参数之前我们先来讲一下指针. 学过C指针的应该都知道,指针变量中保存的是一个地址,程序可以根据所保存的地址 ...
- Senparc.Weixin.MP SDK 微信公众平台开发教程 索引
Senparc.Weixin.MP SDK从一开始就坚持开源的状态,这个过程中得到了许多朋友的认可和支持. 目前SDK已经达到比较稳定的版本,这个过程中我觉得有必要整理一些思路和经验,和大家一起分享. ...
- Linux CentOS PhpMyAdmin安装
安装好PHP,Apache和MySQL程序后,为了管理MySQL数据库,我们需要安装phpMyAdmin程序.下面是关于如何在centos安装phpMyAdmin程序的方法.1.管理员root身份登录 ...
- java.lang.NoSuchMethodError: com.google.common.collect.Maps.newConcurrentMap()Ljava/util/concurrent/ConcurrentMap;
在storm启动topo的时候,报错: java.lang.NoSuchMethodError: com.google.common.collect.Maps.newConcurrentMap()Lj ...
- SVN中trunk,branches,tags用法详解
原文地址:http://www.cnblogs.com/dafozhang/archive/2012/06/28/2567769.html Subversion有一个很标准的目录结构,是这样的.比如项 ...
- 高仿QQ即时聊天软件开发系列之一开端
前段时间在园子里看到一个大神做了一个GG2014IM软件,仿QQ的,那感觉···,赶快下载源码过来试试,还真能直接跑起来,效果也不错.但一看源码,全都给封装到了ESFramework里面了,音视频那部 ...
- CSS学习笔记总结和技巧
跟叶老师说项目,他叫我写一个静态首页,看起来挺简单的,但是下手才发现在真的不会怎么下手啊,什么模型啊模块啊都不懂,写毛线啊!! 如图:页面下拉还有侧栏,中间内容等. 可是答应跟老师做了,不能怂啊,于是 ...
- [算法]分治算法(Divide and Conquer)
转载请注明:http://www.cnblogs.com/StartoverX/p/4575744.html 分治算法 在计算机科学中,分治法是建基于多项分支递归的一种很重要的算法范式.字面上的解释是 ...