hdu 4571 Travel in time (floyd+分组背包)
来源:互联网 发布:王者荣耀美化软件 编辑:程序博客网 时间:2024/06/05 02:52
题意:在T秒内从S到E,中间可以参观景点,每个景点有个价值vi,每次只能参观比上次价值大的景点,问最后能获得的最大的价值和是多少。
思路:首先用floyd处理下任意两点的距离。dp[i][j]表示最后到达i点并参观i所在景点时花费了时间j所能获得的最大价值,然后把景点按价值排序,把价值相同的放在一起,剩下就是个分组背包的问题了。。。由于最开始想要直接获得dp的值,要考虑到达i点不参观的情况,可能是写搓了,各种wa,后来一想,直接定义成到达i点并参观完i点的景点的最大价值,这样就好写多了,只要最后算一下从各个点到E的距离就行了。状态的定义和编码复杂度也很有关系啊。。。
代码:
#include<iostream>#include<cstdio>#include<cstring>#include<string>#include<algorithm>#include<map>#include<queue>#include<stack>#include<cmath>#include<vector>#define inf 0x3f3f3f3f#define Inf 0x3FFFFFFFFFFFFFFFLL#define eps 1e-9#define pi acos(-1.0)using namespace std;typedef long long ll;const int maxn=100+10;const int maxt=300+10;int dp[maxn][maxn][maxt],dis[maxn][maxn],vv[maxn],cc[maxn];int n,m,S,E,T,N;struct Node{ int val; vector<int>vt; bool operator <(const Node &a) const { return val<a.val; }}node[maxn],nd[maxn];void Init(){ for(int i=0;i<=n;++i) for(int j=0;j<=n;++j) dis[i][j]=(i==j)?0:inf; for(int i=0;i<maxn;++i) node[i].vt.clear();}void floyd(){ for(int k=0;k<n;++k) for(int i=0;i<n;++i) for(int j=0;j<n;++j) dis[i][j]=min(dis[i][j],dis[i][k]+dis[k][j]);}void solve(){ memset(dp,0xff,sizeof(dp)); for(int i=0;i<n;++i) if(dis[S][i]<=T) dp[0][i][dis[S][i]]=0; int u,v,size,t; for(int i=1;i<=N;++i) { for(u=0;u<n;++u) for(int j=0;j<=T;++j) dp[i][u][j]=dp[i-1][u][j]; size=nd[i].vt.size(); for(int k=0;k<size;++k) { v=nd[i].vt[k]; for(int u=0;u<n;++u) for(int j=T;j>=0;--j) { if(dp[i-1][u][j]==-1) continue; t=j+dis[u][v]+cc[v]; if(t<=T) dp[i][v][t]=max(dp[i][v][t],dp[i-1][u][j]+vv[v]); } } } for(u=0;u<n;++u) for(int i=0;i<=T;++i) if(i+dis[u][E]<=T) dp[N][E][i+dis[u][E]]=max(dp[N][u][i],dp[N][E][i+dis[u][E]]);}int main(){ //freopen("in.txt","r",stdin); //freopen("out.txt","w",stdout); int t,tcase=0; scanf("%d",&t); while(t--) { tcase++; scanf("%d%d%d%d%d",&n,&m,&T,&S,&E); Init(); for(int i=0;i<n;++i) scanf("%d",&cc[i]); for(int i=0;i<n;++i) { scanf("%d",&vv[i]); node[i].val=vv[i]; node[i].vt.push_back(i); } sort(node,node+n); N=1; nd[N]=node[0]; int u,v,w; for(int i=1;i<n;++i) { v=node[i].vt[0]; if(nd[N].val==node[i].val) nd[N].vt.push_back(v); else { nd[++N].vt.clear(); nd[N].vt.push_back(v); nd[N].val=node[i].val; } } for(int i=0;i<m;++i) { scanf("%d%d%d",&u,&v,&w); dis[u][v]=dis[v][u]=min(dis[u][v],w); } floyd(); solve(); int ans=0; for(int i=0;i<=T;++i) ans=max(ans,dp[N][E][i]); printf("Case #%d:\n%d\n",tcase,ans); } return 0;}
0 0
- hdu 4571 Travel in time (floyd+分组背包)
- hdu 4571 Travel in time(floyd+dp)
- floyd+动态规划 hdu-4571-Travel in time
- hdu 4571 Travel in time(Floyd+记忆化)
- hdu 4571 Travel in time (Floyd+记忆化搜索)
- HDU 4571 - Travel in time(Floyd+dijkstra+dp)
- HDU-4571 Travel in time (Floyd&&(DFS||DP))
- HDU 4571Travel in time 最短路+01背包
- 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 4571 Travel in time 解题报告
- hdu 4571 Travel in time(SPFA+DP)
- Hdu 4571 Travel in time(dp)
- LAMP的两种安装方式
- js(eval)解密工具
- Convolutional Neural Networks
- LR 关联函数的边界值可以为参数
- 海量小文件问题综述
- hdu 4571 Travel in time (floyd+分组背包)
- 局部变量的指针和局部指针变量是两个不同概念
- sql ORACLE(六): 集合操作
- 【原创】头文件、宏定义、条件编译、避免头文件重复包含
- 喜欢Vim,只因为可以不用鼠标
- leetcode: Path Sum II
- Windows 8 应用隐私声明——AnyRadio
- C语言作用域和static keyword
- nyoj 712 探寻宝藏