【jzoj3737】【挖宝藏】【斯坦纳树】【状态压缩动态规划】
来源:互联网 发布:tower windows 破解版 编辑:程序博客网 时间:2024/05/16 08:55
题目大意
解题思路
每层单独考虑,就是平面图的最小生成树,斯坦纳树。设F[i][j][s]表示当前在(i,j)目标点的选取情况为s的最小花费,观察可知当前状态可以由邻近节点走一步得来,也可以由当前节点s的两个子状态得来,注意减去重复的当前点的花费。我们可以枚举s,先更新所有点s的答案,再通过spfa更新其他点的答案。
对于多层,考虑先把下一层解决,把下一层当作一个目标点加在当前层上,每个点都要这样做,这样就可以解决从当前层走到最后的花费,问题就可以解决了。
code
#include<cmath>#include<cstdio>#include<cstring>#include<algorithm>#define LF double#define LL long long#define Min(a,b) ((a<b)?a:b)#define Max(a,b) ((a>b)?a:b)#define Fo(i,j,k) for(int i=j;i<=k;i++)#define Fd(i,j,k) for(int i=j;i>=k;i--)using namespace std;int const Mxn=10,Mxa=1<<10,Mxsi=1e4,Inf=1e9;int H,N,M,A[Mxn+9][Mxn+9][Mxn+9],F[Mxn+9][Mxn+9][Mxa+9], B[Mxn+9][Mxn+9][2],Q[Mxsi+9][2],Inq[Mxn+9][Mxn+9],K[Mxn+9], W[4][2]={{-1,0},{0,-1},{0,1},{1,0}},G[Mxn+9][Mxn+9];int main(){ //freopen("treasure.in","r",stdin); //freopen("treasure.out","w ",stdout); freopen("d.in","r",stdin); freopen("d.out","w ",stdout); scanf("%d%d%d",&H,&N,&M); Fo(i,1,H)Fo(j,1,N)Fo(k,1,M)scanf("%d",&A[i][j][k]); //Fo(j,1,N)Fo(k,1,M)Fo(l,1,Mxa)F[j][k][l]=Inf; Fo(i,1,H){ scanf("%d",&K[i]); Fo(j,1,K[i])scanf("%d%d",&B[i][j][0],&B[i][j][1]); } Fd(i,H,1){ K[i]++;int Mxs=(1<<K[i])-1; Fo(j,1,N)Fo(k,1,M){ F[j][k][0]=A[i][j][k]; Fo(l,1,Mxs)F[j][k][l]=Inf; F[j][k][1<<(K[i]-1)]=G[j][k]+A[i][j][k]; } Fo(j,1,K[i]-1)F[B[i][j][0]][B[i][j][1]][1<<(j-1)]=A[i][B[i][j][0]][B[i][j][1]]; //Fo(j,1,K)scanf("%d%d",&B[j][0],&B[j][1]),F[B[j][0]][B[j][1]][1]=F[B[j][0]][B[j][1]][0]; Fo(s,1,Mxs){ int He=0,Ti=0; for(int ss=s;ss;ss=(ss-1)&s)Fo(j,1,N)Fo(k,1,M) F[j][k][s]=Min(F[j][k][s],F[j][k][ss]+F[j][k][s-ss]-A[i][j][k]); //Fo(j,1,K)F[B[j][0]][B[j][1]][s]=F[B[j][0]][B[j][1]][s^(1<<(j-1))]; Fo(j,1,N)Fo(k,1,M)Q[++Ti][0]=j,Q[Ti][1]=k,Inq[j][k]=1; while(He!=Ti){ int X=Q[++He][0],Y=Q[He][1]; Fo(l,0,3)if(F[X+W[l][0]][Y+W[l][1]][s]>F[X][Y][s]+A[i][X+W[l][0]][Y+W[l][1]]){ F[X+W[l][0]][Y+W[l][1]][s]=F[X][Y][s]+A[i][X+W[l][0]][Y+W[l][1]]; if(!Inq[X+W[l][0]][Y+W[l][1]]){ Inq[X+W[l][0]][Y+W[l][1]]=1; Q[++Ti][0]=X+W[l][0]; Q[Ti][1]=Y+W[l][1]; if((Q[Ti][0]<1)||(Q[Ti][1]<1)){ int bb; bb++; } } } Inq[X][Y]=0; } } Fo(j,1,N)Fo(k,1,M)G[j][k]=F[j][k][Mxs]; } int Ans=Inf; Fo(j,1,N)Fo(k,1,M)Ans=Min(Ans,G[j][k]); printf("%d",Ans); return 0;}
0 0
- 【jzoj3737】【挖宝藏】【斯坦纳树】【状态压缩动态规划】
- 【JZOJ3737】【NOI2014模拟7.11】挖宝藏(treasure) 状压DP+斯坦纳树+SPFA
- JZOJ3737 挖宝藏(treasure)
- 【JZOJ3737】【NOI2014模拟7.11】挖宝藏(treasure)
- 【HDU4085】Peach Blossom Spring【斯坦纳树】【状态压缩】
- 状态压缩动态规划
- 状态压缩动态规划
- 状态压缩动态规划
- 状态压缩动态规划
- 状态压缩动态规划
- 动态规划!状态压缩
- 状态压缩动态规划
- 状态压缩.宝藏正解。
- 【状态压缩】【动态规划】电子竞技
- 【状态压缩】【动态规划】坑爹题
- 什么是状态压缩动态规划
- 动态规划之状态压缩
- 动态规划之状态压缩
- spring中的AOP详解
- flaskWeb开发(基于python的web开发实战)-第一部分-Flask简介
- String类中两种实例化对象的区别
- Kotlin的属性委托:无上下文情况下Android的赋值(KAD 15)
- 文章标题
- 【jzoj3737】【挖宝藏】【斯坦纳树】【状态压缩动态规划】
- 我的H5生涯2
- 鸟哥的linux私房菜学习笔记《二十六》ACL权限管理
- git 配置user和email信息
- Spring多数据源配置方式一
- 5016. 数列
- sort对二维字符数组排序
- React Native 中POST请求参数传递
- new写在循环内部和外部的区别