HDU 4571Travel in time 最短路+01背包
来源:互联网 发布:自学计算机游戏编程 编辑:程序博客网 时间:2024/06/06 02:10
题意:一些点,之间有双向边,每个点可以获得一个si值,但是也要付出相应ci的代价,你可以只经过那个点但是不获得那个si值,每次获得的si值要满足,大于最近一次获得的si值,也可以说,获得si值的顺序是严格从小到大的。
做的时候,先要考虑构造dp的模型,dp[i][j]就是时间为i最近一次是获得sj的值,此时获取的si的总值。初始化考虑是否获得初始点S的si值,求答案时,考虑是否获得E的si值,其实就是一样的,考虑是否获得每个点的si值作为初始化,考虑最后一次为是否获得每个点的si值做为最终答案,也就是两个循环的事。
坑来了。坑在ci可能为0,也就是说,如果你直接背包同一个t的状态可能有的先背有的后背,不同背的顺序得到的答案就会前后不一致。那么就对si排序,保证顺序是按照si来的,这样不管先背后备,就是按照si背的,不会有错。
还有一个坑,紫书的floyed打印错了,导致直接wa的没想法。
大概就是这些要注意的了。
代码:
#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>using namespace std;const int INF = 301;int dp[333][111];int dis[111][111];int Ci[111],Si[111];struct Node{ int o; bool operator < (const Node&rhs)const{ return Si[o]<Si[rhs.o]; }}mp[111];int main(){// freopen("data.in","r",stdin); int W,cas=1,ans,N,M,T,S,E,u,v,l; scanf("%d",&W); while(W--){ scanf("%d%d%d%d%d",&N,&M,&T,&S,&E); for(int i=0;i<N;i++) scanf("%d",&Ci[i]); for(int i=0;i<N;i++) scanf("%d",&Si[i]); for(int i=0;i<N;i++) mp[i].o = i; sort(mp,mp+N); for(int i=0;i<N;i++) for(int j=0;j<N;j++){ dis[i][j]=INF; if(i==j) dis[i][j] = 0; } while(M--){ scanf("%d%d%d",&u,&v,&l); if(dis[u][v]>l){ dis[u][v] = l; dis[v][u] = l; } } for(int i=0;i<N;i++) for(int j=0;j<N;j++) for(int k=0;k<N;k++) if(dis[j][i]<=T && dis[i][k]<=T) dis[j][k] = min(dis[j][k],dis[j][i]+dis[i][k]); memset(dp,-1,sizeof dp); for(int i=0;i<N;i++) if(Ci[i]+dis[S][i] <= T) dp[Ci[i]+dis[S][i]][i] = Si[i];// for(int i=0;i<=T;i++)// for(int j=0;j<N;j++){// int mj = mp[j].o;// for(int k=0;k<N;k++){// int mk = mp[k].o;// if(i - dis[mk][mj] - Ci[mj] >= 0 && dp[i - dis[mk][mj] - Ci[mj]][mk]!=-1){// if(Si[mk] < Si[mj]){// if(dp[i][mj]==-1 || dp[i][mj] < dp[i - dis[mk][mj] - Ci[mj]][mk] + Si[mj]){// dp[i][mj] = dp[i - dis[mk][mj] - Ci[mj]][mk] + Si[mj];// }// }// }// }// } for(int i=0;i<=T;i++) for(int j=0;j<N;j++){ int mj = mp[j].o; if(dp[i][mj] == -1) continue; for(int k=0;k<N;k++){ int mk = mp[k].o; if(Si[mj] < Si[mk] && i + dis[mj][mk] + Ci[mk] <= T){ if(dp[i + dis[mj][mk] + Ci[mk]][mk]==-1 || dp[i + dis[mj][mk] + Ci[mk]][mk] < dp[i][mj] + Si[mk]){ dp[i + dis[mj][mk] + Ci[mk]][mk] = dp[i][mj] + Si[mk]; } } } } ans=0; for(int j=0;j<N;j++) for(int i=0;i<=T-dis[j][E];i++) ans = max(ans,dp[i][j]); printf("Case #%d:\n",cas++); printf("%d\n",ans); } return 0;}
0 0
- HDU 4571Travel in time 最短路+01背包
- hdu 4571 Travel in time 最短路+dp
- hdu 4571 Travel in time (floyd+分组背包)
- hdu 4571 Travel in time
- hdu 4571 Travel in time
- HDU -4571--Travel in Time
- hdu 4571 Travel in time
- hdu 4571 Travel in time
- HDU-4571-Travel in time
- HDU 4571 Travel in time
- hdu In Action-最短路+01背包
- HDU 4571 Travel in time 解题报告
- hdu 4571 Travel in time(SPFA+DP)
- Hdu 4571 Travel in time(dp)
- hdu 4571 Travel in time(floyd+dp)
- hdu 2433 Travel 最短路
- hdu 3339 In Action spfa最短路+01背包
- hdu 3339 In Action(最短路+01背包)
- 最近最近
- 【调研】特殊网络图像的敏感词检测,图像文本检测提取
- 怎么检测jquery库是否加载
- int sqrt(int x)
- PAT1010. 一元多项式求导 (25)
- HDU 4571Travel in time 最短路+01背包
- github 学习
- 1016
- OpenMP和MPI的区别(不断总结、汇总、更新中)
- 把两个排好序的数组,升序插入到另一个数组
- 表、触发器、事务、存储过程
- [LeetCode OJ]Linked List Cycle
- 基于事件的 JavaScript 编程:异步与同步
- leetcode N-Queens