HDU-4571-spfa,记忆化搜索,背包,DP
来源:互联网 发布:tough cookie.js 编辑:程序博客网 时间:2024/05/19 18:13
https://cn.vjudge.net/contest/165541#problem/G
G题可以用记忆化搜索。
大致题意就是给一些景点,有边权(路上的话费)和点权(游览的时间),和每个景点的满意度,问你最大满意度的方案。
因为可以有的点经过而不访问,并且景点之间可能有好多路。
所以先用floyd来确定任意两点的最小距离
(这样就包含了pass某些点的情况)
然后用记忆化搜索,用t和顶点的标号来限制。
背包也可以写,还没怎么搞明白。。
还有用floyd进行的DP
或者spfa下进行的DP
注意:在进行spfa的时候一定不要影响最基本的松弛条件。
用spfa求的最长路(
需要注意的是越过某些景点的操作在floyd的过程中也进行过了,所以只要老老实实的spfa就行。
)
还要记录当前话费的状态,防止出现t的大小超出限制。
很好的spfa应用。
还要加两个点。
/*用spfa的方法。
注意 要建立一个超级源点和 超级汇点。
正常的spfa只有边权。
如果还有点权,那么只要遍历的时候加上的时候就行了。
但对于第一个点,是不能进行取舍的。因为他是肯定要入栈的
所以要加一个超级源点记录那些visit第一个点的方法
第二就是搞一个超级汇点,目的是为了终点的判断。
然后在进行spfa的同时进行dp
注意先用floyd走一遍,然后在进行最短路
*/
spfa
#include <iostream>#include <cstdlib>#include <cstdio>#include <cstring>#include <queue>#include <stack>#include <string>using namespace std;const int maxn=300;int s,e;int T;int m,n;int cost[maxn];int val[maxn];int g[maxn][maxn];void floyd(){ for(int i=0;i<m+2;i++) g[i][i]=0; for(int k=0;k<m;k++) for(int i=0;i<m;i++) for(int j=0;j<m;j++) g[i][j]=min(g[i][k]+g[k][j],g[i][j]);}int spfa(int first,int second){ //int d[maxn]; bool vis[maxn][maxn]; int dp[maxn][maxn]; memset(dp,0,sizeof(dp)); int ans=-1; memset(vis,false,sizeof(vis)); queue<int>q; queue<int>qq; q.push(first); qq.push(0); //d[first]=0; vis[first][0]=true; while(!q.empty()) { int u=q.front();q.pop(); int uct=qq.front();qq.pop(); vis[u][uct]=false; if(u==second) ans=max(ans,dp[u][uct]); for(int i=0;i<m;i++) { if((i==u)||(val[u]>=val[i]&&i!=second))continue; int costing=uct+cost[i]+g[u][i]; if((costing<=T)&&(dp[i][costing]<dp[u][uct]+val[i])) //if ((dp[i][costing] < dp[u][uct] + val[i])&&(costing<=T)) { dp[i][costing]=dp[u][uct]+val[i]; if(!vis[i][costing]) { //vis[i][costing]=true; q.push(i); qq.push(costing); vis[i][costing]=true; } } } } return ans;}int main(){ int tt; int a,b,c; cin>>tt; for(int sss=1;sss<=tt;sss++){ memset(g,0x3f,sizeof(g)); cin>>m>>n>>T>>s>>e; for(int i=0;i<m;i++) cin>>cost[i]; for(int i=0;i<m;i++) cin>>val[i]; for(int i=0;i<n;i++) {cin>>a>>b>>c; if(c<g[a][b]) { g[a][b]=c; g[b][a]=c; } } floyd(); int ss=m; int tt=m+1; cost[ss]=cost[tt]=0; val[ss]=val[tt]=0; for(int i=0;i<m;i++) if(g[s][i]!=0x3f3f3f3f) g[ss][i]=g[s][i]; //g[ss][tt]=g[s][e]; for(int i=0;i<m;i++) if(g[i][e]!=0x3f3f3f3f) g[i][tt]=g[i][e]; g[ss][tt]=g[s][e]; m+=2; printf("Case #%d:\n",sss); cout<<spfa(ss,tt)<<endl;} return 0;}
记忆化搜索
#include<iostream>#include<cstdio>#include<list>#include<algorithm>#include<cstring>#include<string>#include<queue>#include<stack>#include<map>#include<vector>#include<cmath>#include<memory.h>#include<set>using namespace std;const int maxn=105;const int INF=0x3f3f3f3f;int dp[maxn][maxn][3*maxn];int cost[maxn];int val[maxn];int a[maxn][maxn];int m,n;int s,e;int T;int floyd(){ for(int i=0;i<m;i++) a[i][i]=0; for(int k=0;k<m;k++) for(int i=0;i<m;i++) for(int j=0;j<m;j++) a[i][j]=min(a[i][k]+a[k][j],a[i][j]); return 0;}void init(){memset(dp,-1,sizeof(dp)); memset(a,0x3f,sizeof(a)); //for(int i=0;i<m;i++) //a[i][i]=0;}int dfs(int x,int value,int t){ if(a[x][e]>t) return -INF; if(dp[x][value][t]!=-1) return dp[x][value][t]; int ans=0; for(int i=0;i<m;i++) { if(a[x][i]!=INF&&value>=val[i]) continue; ans=max(ans,dfs(i,val[i],t-cost[i]-a[x][i])+val[i]); } dp[x][value][t]=ans; return ans;}int main(){ int ttt; int a1,b,c; cin>>ttt; for(int ss=1;ss<=ttt;ss++){ init(); cin>>m>>n>>T>>s>>e; for(int i=0;i<m;i++)cin>>cost[i]; for(int i=0;i<m;i++)cin>>val[i]; for(int i=0;i<n;i++) { cin>>a1>>b>>c; if(c<a[a1][b]) {a[a1][b]=c; a[b][a1]=c; } } printf("Case #%d:\n",ss); floyd(); printf("%d\n",dfs(s,0,T));} return 0;}
阅读全文
0 0
- HDU-4571-spfa,记忆化搜索,背包,DP
- hdu :4359(记忆化搜索DP)
- hdu 4293 Groups dp 记忆化搜索
- hdu 2571 命运 (记忆化搜索+dp)
- HDU 1208 DP || 记忆化搜索
- HDU 1508 DP || 记忆化搜索
- hdu 4826(dp + 记忆化搜索)
- HDU 4968 DP||记忆化搜索
- HDU 5001 概率DP || 记忆化搜索
- hdu 1069 记忆化搜索+dp
- hdu 5179 数位dp+记忆化搜索
- hdu 机器人路径 dp+记忆化搜索
- hdu 1078 (dp记忆化搜索)
- hdu 4540 dp 记忆化搜索
- HDU 1501 Zippe(dp记忆化搜索)
- hdu 5898 数位dp,记忆化搜索
- [DP/记忆化搜索] HDU 1078
- HDU 1428 漫步校园(SPFA+记忆化搜索)
- java线程启动
- Java实现二叉树的深度
- 获取canvas中鼠标的坐标
- Mooc 面向对象程序设计 week2作业
- Java实现几种常见排序方法
- HDU-4571-spfa,记忆化搜索,背包,DP
- Python爬虫神器PyQuery的使用方法
- Node入门
- kotlin的必修之路
- 20170601
- 数据库分年度统计数据量
- [Linux]用户(user)和用户组(group)管理与操作教程
- windows内核&驱动
- 463.整数排序