题意:给一个无向图和时间限制,景点到景点需要时间,每游览一个景点会得到相应价值也会花费相应时间,而且你下一个游览的景点的价值必须比现在的大。求从起始景点到结束景点获得的最大价值。你可以路过任意一个景点而不游览,这样也不花费时间。
首先,肯定要求出景点间的最短距离,因为任意景点都可以只路过,所以增加一个虚拟起点,这里景点编号0~n-1,所以虚拟起点定为n。初始化:cost【n】【be】=cost【be】【n】=0(be为起始景点),然后Floyd、Spfa什么的求最短路径。
其次,最大价值需要dp求解:
前提条件:val[i]>val[t]&&sum+cost[t][i]+need[i]+cost[i][en]<=lim
关系方程:dp[sum][t]=max(dp[sum][t],deal(sum+cost[t][i]+need[i],i)+val[i]);
其中sum为当前花费时间,t为此时游览的景点,lim为时间限制,val数组为景点价值,cost数组为最短路径花费时间,need数组为游览这个景点花费时间。(i从0~n-1)
#include<cstdio> #include<algorithm> using namespace std; int n,lim,en; int need[305],val[305]; int cost[305][305],dp[305][305]; int deal(int sum,int t) { if(dp[sum][t]!=-1)return dp[sum][t]; dp[sum][t]=0; for(int i=0; i<n; i++) if(val[i]>val[t]&&sum+cost[t][i]+need[i]+cost[i][en]<=lim) dp[sum][t]=max(dp[sum][t],deal(sum+cost[t][i]+need[i],i)+val[i]); return dp[sum][t]; } int main() { int T,t,m,be,i,j,k; scanf("%d",&T); for(t=1; t<=T; t++) { memset(dp,-1,sizeof(dp)); scanf("%d%d%d%d%d",&n,&m,&lim,&be,&en); for(i=0; i<n; i++) scanf("%d",&need[i]); for(i=0; i<n; i++) scanf("%d",&val[i]); for(i=0; i<=n; i++) { for(j=0; j<=n; j++) cost[i][j]=12345678; cost[i][i]=0; } cost[n][be]=cost[be][n]=0; for(i=0; i<m; i++) { int u,v,c; scanf("%d%d%d",&u,&v,&c); if(cost[u][v]>c)cost[u][v]=cost[v][u]=c; } for(k=0; k<=n; k++) for(i=0; i<=n; i++) for(j=0; j<=n; j++) if(cost[i][j]>cost[i][k]+cost[k][j])cost[i][j]=cost[i][k]+cost[k][j]; printf("Case #%d:\n",t); if(cost[n][en]>lim)printf("0\n"); else printf("%d\n",deal(0,n)); } return 0; } /* 3 4 4 22 0 3 1 1 1 1 5 7 9 12 0 1 10 1 3 10 0 2 10 2 3 10 21 */