HDU-4568-Hunter
来源:互联网 发布:java之父现在在做什么 编辑:程序博客网 时间:2024/05/21 10:07
题意大致是说给你一个矩阵,其中某些位置有一些宝藏,让你尽可能的取出宝藏并花费最少的代价。矩阵中为-1的是不能走的,另外走的代价为你经过格子的值,你可以选择任意地点进入与出来。
思路:我先用的Spfa把所有宝藏之间的最短距离算出来,并算出从当前宝藏离开的最短路径。然后就是类似于TSP的DP了,需要注意的是处理-1的情况,也比较简单。后面的转移方程式为dp[j][i]=min(dp[j][k]+dis[k][i]) 其中dp[j][i]表示当前位置在j,得到的宝藏状态为i还需要多少代价完成拿所有的能拿的宝藏。
代码:
#include<cstdio>#include<cstring>#include<iostream>#include<queue>using namespace std;const int inf=1<<29;const int maxn=210;int movex[4]={1,-1,0,0},movey[4]={0,0,1,-1};int n,m,k,a[maxn][maxn],fx[16],fy[16],fo[maxn][maxn],dist[maxn*maxn],dis[16][16];int dp[16][1<<13];bool vis[maxn*maxn];queue<int> q;void Init(){ memset(fo,0,sizeof(fo));}bool isborder(int x,int y){ if(x<0||y<0||x>=n||y>=m) return true; return false;}void Spfa(int sx,int sy){ for(int i=0;i<=m*n;i++) dist[i]=inf; if(a[sx][sy]==-1) return; dist[sx*m+sy]=0; q.push(sx*m+sy); while(!q.empty()) { int u=q.front(); vis[u]=0; q.pop(); for(int i=0;i<4;i++) { int itx=u/m+movex[i]; int ity=u%m+movey[i]; if(isborder(itx,ity)) { dist[n*m]=min(dist[n*m],dist[u]); } else if(a[itx][ity]!=-1) { if(dist[itx*m+ity]>dist[u]+a[itx][ity]) { dist[itx*m+ity]=dist[u]+a[itx][ity]; if(!vis[itx*m+ity]) { q.push(itx*m+ity); vis[itx*m+ity]=1; } } } } }}void solve(){ for(int i=1;i<=k;i++) { Spfa(fx[i],fy[i]); for(int j=1;j<=k;j++) dis[i][j]=dist[fx[j]*m+fy[j]]; dis[i][k+1]=dist[n*m]; } int res=k,fin=(1<<k)-1; bool is=false; if(k>1) { for(int i=1;i<=k;i++) { for(int j=1;j<=k;j++) if(i!=j&&dis[i][j]!=inf) { is=true; break; } if(!is) { res--; fin^=(1<<(i-1)); } } } for(int i=1;i<=k;i++) for(int j=0;j<=fin;j++) dp[i][j]=inf; for(int i=1;i<=k;i++) dp[i][1<<(i-1)]=dis[i][k+1]+a[fx[i]][fy[i]]; for(int i=0;i<=fin;i++) for(int j=1;j<=k;j++) for(int l=1;l<=k;l++) if(l!=j&&(!(i&(1<<(l-1))))) dp[l][i|(1<<(l-1))]=min(dp[l][i|(1<<(l-1))],dp[j][i]+dis[j][l]); int ans=inf; for(int i=1;i<=k;i++) ans=min(ans,dp[i][fin]+dis[i][k+1]); if(ans==inf) printf("0\n"); else printf("%d\n",ans);}int main(){ int T; scanf("%d",&T); while(T--) { scanf("%d%d",&n,&m); for(int i=0;i<n;i++) for(int j=0;j<m;j++) scanf("%d",&a[i][j]); scanf("%d",&k); for(int i=1;i<=k;i++) { scanf("%d%d",&fx[i],&fy[i]); fo[fx[i]][fy[i]]=i; } solve(); } return 0;}
0 0
- hdu 4568 Hunter
- HDU 4568 Hunter
- hdu-4568-Hunter
- HDU 4568 Hunter TSP_DP
- hdu 4568 Hunter
- HDU-4568-Hunter
- 【TSP】 HDU 4568 Hunter
- hdu 4568 hunter
- HDU 4568 Hunter
- HDU 4568 Hunter
- HDU 4568 Hunter 解题报告
- HDU 4568 Hunter (状态压缩)
- HDU 4568 Hunter ( TSP + 状态压缩 )
- hdu 4568 Hunter (旅行商问题)
- Hdu 4568 Hunter 2013长沙邀请赛
- HDU 4568 Hunter ( TSP + 状态压缩 )
- hdu 4568 Hunter(spfa预处理 + 状压dp)
- Hdu 4568 Hunter(状压dp)
- acm-字典重排
- js 导出table并保存为excel文件
- Java EE7和Maven工程入门---- 一个简单Maven工程的结构
- 将5350 i2c clk设置为gpio 中断模式的方法
- (五)ROS主题理解
- HDU-4568-Hunter
- (六)ROS服务和参数理解
- “4K”时代将来临!标准/技术一网打尽
- 20140717
- 获取事件对象
- 关于MAVEN找不到JDK的那点事
- 关于什么样的用户权限可以把计算机加入windows domain的辩论
- CRC32算法详细推导(3)
- 黑马程序员-ARC,Block与protocol