题意:

给你N个点,M条双向边,L个饭店,S代表起点,T代表时间限制

给你M个a,b,c 表示走过边(a,b)的花费为c

给你L个j,e 表示点j'旁边有个饭店,在该饭店吃饭需要时间e

  • 2 ≤ n ≤ 300

  • 1 ≤ m ≤ 5,000

  • 1 ≤ l ≤ 16

  • 1 ≤ s ≤ n

  • 1 ≤ t ≤ 100,000

  • 1 ≤ ai, bi ≤ n

  • 1 ≤ ci ≤ 1,000

  • 1 ≤ ji ≤ n

  • 1 ≤ ei ≤ 15

想法:  训练赛的时候我就想到先用弗洛伊德预处理,然后就把图变成了一个只有16个点的图,后面我想用状态压缩,也想过用dp,当时以为这不能用dp,因为dp有后效性

后面自己用dfs写TLE了

比赛之后HNU的学长在群里说记忆化搜索就是dp,我肯定是因为没有记忆化。。。

等他将完这题的时候我才知道。。 原来状态还可以酱紫转移的。。  涨姿势了。。

PS: 写代码写了好久才写出来。。。 真是无语。。  知道怎么做居然写不出来。。  LCB 教我用递归写了一次。。 昨晚还是TLE了。。  今早上用for循环写AC了。。

代码:

#include <stdio.h>
#include <string.h>
#define maxn 305
#define maxt 100005
#define REP(i,n) for(int i= 1; i<= (n); i++)
int map[maxn][maxn];
int dis[maxn][maxn];
int n, m, l, s, t;
int pos[20], c[20];
int dp[1<<17][20];
int cnt[1<<17][20];
int ans;
int min(int x, int y)
{
return x< y? x: y;
}
void Floyd()
{
REP(i, n) REP(j, n)
dis[i][j]= map[i][j];
REP(u, n) REP(v, n) REP(w, n)
if(dis[u][v] + dis[u][w] < dis[v][w])
dis[v][w]= dis[u][v] + dis[u][w];
}
/*
void get(int ss, int k)
{
//printf("%d %d %d %d %d %d\n",ss,k,pos[k],dp[ss][k], dis[s][pos[k]],dp[ss][k]+ dis[ss][pos[k]]);
if(dp[ss][k]+ dis[s][pos[k]]> t)
return;
//  printf("xx\n");
if(cnt[ss][k]> ans)
ans= cnt[ss][k];
for(int i= 1; i<= l; i++)
if(ss&(1<<i))continue;
else
{
int xx= dp[ss][k] + dis[pos[k]][pos[i]] + c[i];
//  printf("%d %d %d %d %d %d\n",xx,dp[s][k], dis[pos[k]][pos[i]],c[i],pos[k],pos[i]);
int hh= ss|(1<<i);
if(dp[hh][i]== -1)
dp[hh][i]= xx;
else
dp[hh][i]= min(dp[hh][i], xx);
cnt[hh][i]= cnt[ss][k] + 1;
get(hh, i);
}
}
*/ //之前的递归代码
int main()
{
while(scanf("%d %d %d %d %d",&n,&m,&l,&s,&t)!=EOF)
{
if(n+m+l+s+t==0)
break;
REP(i, n) REP(j, n)
map[i][j]= maxt;
for(int i= 1; i<= m; i++)
{
int a, b, c;
scanf("%d %d %d",&a,&b,&c);
map[a][b]= map[b][a]= c;
}
for(int i= 1; i<= l; i++)
scanf("%d %d",&pos[i], &c[i]);
pos[0]= s;
Floyd();
memset(dp, -1, sizeof(dp));
memset(cnt, 0, sizeof(cnt));
dp[1][0]= 0;
dis[s][s]= 0;
ans= 0;
for(int num= 1; num< (1<<(l+1)); num+=2) //用一个L+1位二进制数表示,其中最低位表示起点S
for(int i= 1; i<= l; i++)
if(num&(1<<i))continue;
else
{
for(int k= 0; k<= l; k++)
if(num&(1<<k) && dp[num][k]!=-1) // 这里要判断dp[num][k]是否非法 因为S点只能在第一步往其他点延伸
{
int xx= dp[num][k] + dis[pos[k]][pos[i]] + c[i];
int hh= num|(1<<i);
if(dp[hh][i]== -1)
dp[hh][i]= xx;
else
dp[hh][i]= min(dp[hh][i], xx);
cnt[hh][i]= cnt[num][k] + 1;
}
}
for(int i= 1; i< (1<< (l+1)); i++)
for(int j= 1; j<= l; j++)
{
if(dp[i][j]!=-1 && dp[i][j] + dis[s][pos[j]]<= t && cnt[i][j]> ans)
ans= cnt[i][j];
}
printf("%d\n",ans);
}
return 0;
} 

HNU 12814 SIRO Challenge(最短路+状态压缩+dp)相关推荐

  1. Light OJ 1316 A Wedding Party 最短路+状态压缩DP

    题目来源:Light OJ 1316 1316 - A Wedding Party 题意:和HDU 4284 差点儿相同 有一些商店 从起点到终点在走过尽量多商店的情况下求最短路 思路:首先预处理每两 ...

  2. 0x56. 动态规划 - 状态压缩DP(习题详解 × 7)

    目录 Problem A. 最短Hamilton路径 ProblemB. 蒙德里安的梦想 Problem C. Corn Fields Problem D. 小国王 Problem E. 炮兵阵地 P ...

  3. 【BZOJ3049】Island Travels,SPFA预处理+状态压缩DP

    传送门(权限题) 3049: [Usaco2013 Jan]Island Travels Time Limit: 10 Sec Memory Limit: 128 MB Submit: 84 Solv ...

  4. [转]状态压缩dp(状压dp)

    状态压缩动态规划(简称状压dp)是另一类非常典型的动态规划,通常使用在NP问题的小规模求解中,虽然是指数级别的复杂度,但速度比搜索快,其思想非常值得借鉴. 为了更好的理解状压dp,首先介绍位运算相关的 ...

  5. bzoj4479: [Jsoi2013]吃货jyy 欧拉回路+状态压缩Dp

    bzoj4479: [Jsoi2013]吃货jyy Description [故事背景] 作为JSOI的著名吃货,JYY的理想之一就是吃遍全世界的美食.要走遍全 世界当然需要不断的坐飞机了.而不同的航 ...

  6. POJ 2411 Mondriaan‘s Dream(最清楚好懂的状压DP讲解)(连通性状态压缩DP)

    poj 2411 Mondriaan's Dream(最清晰的状压DP解析) 闫氏DP大法好 我们这里是一列一列地来,因为是一个棋盘性的状态压缩DP,从哪个方向都一样 摆放的小方格总方案数 等价于 横 ...

  7. BZOJ1688|二进制枚举子集| 状态压缩DP

    Disease Manangement 疾病管理 Description Alas! A set of D (1 <= D <= 15) diseases (numbered 1..D) ...

  8. hdu1074 状态压缩dp+记录方案

    题意:       给你一些作业,每个作业有自己的结束时间和花费时间,如果超过结束时间完成,一天扣一分,问你把n个作业完成最少的扣分,要求输出方案. 思路:       状态压缩dp,记录方案数的地方 ...

  9. FZU-2218 Simple String Problem(状态压缩DP)

    原题地址: 题意: 给你一个串和两个整数n和k,n表示串的长度,k表示串只有前k个小写字母,问你两个不含相同元素的连续子串的长度的最大乘积. 思路: 状态压缩DP最多16位,第i位的状态表示第i位字母 ...

  10. 《算法竞赛进阶指南》打卡-基本算法-AcWing 91. 最短Hamilton路径:位运算、状态压缩dp、dp

    文章目录 题目解答 题目链接 题目解答 分析: 状态压缩dp是用二进制数来表示状态. 数据范围n = 20, 那么状态总量就是2202^{20}220个状态. 可以按照以下思路去思考: 哪些点被用过 ...

最新文章

  1. python量化投资必背代码-基于python的开源量化交易,量化投资架构
  2. iOS之深入解析weak关键字的底层原理
  3. alv 刷新_钜献 | 60小时刷新你的雅思托福成绩!明早9点我们要搞事情了!
  4. 高考临考突发情况应急预案大全
  5. java写hive自定义函数_hive自定义函数的实现和执行
  6. 如何优雅的关闭 Spark Streaming 程序(2种思路)
  7. linux ssh客户端_WinSCP软件双系统(Win-Linux)文件传输教程
  8. c 语言 移位四舍五入,关于C 语言中的四舍五入问题
  9. 接触线叉环插座行业调研报告 - 市场现状分析与发展前景预测
  10. 彩虹代刷网用php几,php彩虹代刷网八套模板源码+教程
  11. 软考初级程序员考试大纲
  12. AUTOSAR CAN Wakeup Analysis
  13. javascript书签工具
  14. OpenLayers 静态图(雷达拼图)叠加
  15. Android 获取定位权限,获取位置信息(国家、地区、经纬)
  16. 再见了 SELECT * !大厂的 MySQL 查询优化方案,确实牛逼!
  17. 怎么区分linux分区,Linux硬盘如何区分
  18. html web 表单
  19. MIPI转LVDS芯片 替代东芝TC358775XBG
  20. 边缘计算网关下山体滑坡监测系统解决方案

热门文章

  1. 周末假期,去一趟安化云台山风景区
  2. 你需要知道的关于元宇宙NFT平台艺术数字藏品交易的一切
  3. html5跳跳蛙小游戏分析,中班科学优秀教案《跳跳蛙》(5页)-原创力文档
  4. cmd无法打开jupyter notebook问题
  5. 为什么压缩卷明明显示有许多空间却无法分出空余空间?
  6. 但行好事莫问前程 学习笔记
  7. 实战:k8s之Longhorn备份恢复-2022.2.26
  8. linux桌面lxde 安装_如何在Arch Linux上安装LXDE桌面
  9. es 精确查找思路以及实现过程
  10. ElasticSearch 一文读懂