zoukankan      html  css  js  c++  java
  • P4308 [CTSC2011]幸福路径 倍增+Floyd

    题意:

    给定一个有向图,每个点有一个点权,给定起点,初始体力为1,经过一条边体力会变为原来的p倍,到达每个点时会得到点权乘上体力的价值,求规划一条路径使得价值和最大,输出保留1位小数

    范围&性质:有向图可能存在环,\(1\le n\le 100,1\le m \le 10^3,0< p<1\)

    分析:

    n很小好像可以做,p固定可以直接倍增

    \(dp[i][j][k]\)表示走\(2^i\)步,从j到达k时得到的价值最大,转移式为

    \[dp[i][j][k]=max(dp[i-1][j][l]+dp[i-1][l][k]\times qpow(p,2^{i-1})) \]

    滚动数组可以消掉倍增那一维

    代码:

    #include<bits/stdc++.h>
    
    using namespace std;
    
    namespace zzc
    {
    	const int maxn = 105;
    	const double eps = 1e-10;
    	int n,m,st;
    	double f[maxn][maxn],dp[maxn][maxn],ans,p,v[maxn];
    	
    	void work()
    	{
    		scanf("%d%d",&n,&m);
    		for(int i=1;i<=n;i++)
    		{
    			scanf("%lf",&v[i]);
    		}
    		scanf("%d",&st);
    		scanf("%lf",&p);
    		
    		for(int i=1;i<=n;i++)
    		{
    			for(int j=1;j<=n;j++)
    			{
    				if(i==j) continue;
    				f[i][j]=-1e10;
    			}
    		}
    		
    		for(int i=1,a,b;i<=m;i++)
    		{
    			scanf("%d%d",&a,&b);
    			f[a][b]=v[b]*p;
    		}
    		
    		for(;p>=eps;p=p*p)
    		{
    			for(int i=1;i<=n;i++)
    			{
    				for(int j=1;j<=n;j++)
    				{
    					dp[i][j]=-1e10;
    				}
    			}
    			
    			for(int k=1;k<=n;k++)
    			{
    				for(int i=1;i<=n;i++)
    				{
    					for(int j=1;j<=n;j++)
    					{
    						dp[i][j]=max(dp[i][j],f[i][k]+f[k][j]*p);
    					}
    				}
    			}
    			memcpy(f,dp,sizeof(dp));
    		}
    		
    		ans=-1e5;
    		for(int i=1;i<=n;i++)
    		{
    			ans=max(ans,f[st][i]);
    		}
    		printf("%.1lf\n",ans+v[st]);
    		
    	}
    	
    }
    
    int main()
    {
    	zzc::work();
    	return 0;
    }
    
  • 相关阅读:
    Python
    Python
    Python
    Python
    python
    python
    Python
    pure css做的pc登陆界面
    MvcAdmin功能介绍
    pure css做的手机版博客园(我自己博客)
  • 原文地址:https://www.cnblogs.com/youth518/p/13666804.html
Copyright © 2011-2022 走看看