zoukankan      html  css  js  c++  java
  • 【BZOJ2306】幸福路径(动态规划,倍增)

    【BZOJ2306】幸福路径(动态规划,倍增)

    题面

    BZOJ

    题解

    不要求确切的值,只需要逼近
    显然可以通过移动(infty)步来达到逼近的效果
    考虑每次的一步怎么移动
    (f[i][j])表示走(i)步到了(j)能够得到的最大权值
    (f[i][v]=max(f[i-1][u])+W[v]*p^i,(u,v)in G)
    这样的复杂度是(O(T(n+m)))(T)是自己设定的步数
    但是这样子逼近精度很慢
    假设(p=0.999999),大概要(10^7)步才能达到目标进度
    这样子显然太慢
    我们考虑如何优化
    既然一步步走很慢,那么我们考虑倍增来走
    首先预处理以下两个点之间的连通性
    (g[i][j][k])表示走了(2^k)步后是否能从(i)(j)
    那么,(f[i][j])表示走了(2^i)步到达(j)能够拿到的最大权值
    这样子每次随意枚举两个点(i,j)来转移,发现有些东西没法记录
    比如枚举两个点,但是不能保证这两个点之间的最优路径是拼接在一起的
    所以我们加一维(f[i][j][l])表示从(i)(j)走了(2^l)步拿到的最优权值
    枚举一个中间点(k)
    (f[i][j][l]=max(f[i][k][l-1]+p^{2^{l-1}}f[k][j][l-1]))
    这样子的复杂度就是(O(n^3log10^7))
    其实(g)也可以不用预处理是否联通,直接把不连通的距离设为(-inf)就行了

    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    #include<set>
    #include<map>
    #include<vector>
    #include<queue>
    using namespace std;
    #define ll long long
    #define RG register
    #define MAX 111
    inline int read()
    {
        RG int x=0,t=1;RG char ch=getchar();
        while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
        if(ch=='-')t=-1,ch=getchar();
        while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
        return x*t;
    }
    struct Line{int v,next;}e[MAX<<4];
    int h[MAX],cnt=1;
    inline void Add(int u,int v){e[cnt]=(Line){v,h[u]};h[u]=cnt++;}
    int n,m,S;
    double f[30][MAX][MAX];
    double W[MAX],p,Ans;
    int main()
    {
    	scanf("%d%d",&n,&m);
    	for(int i=1;i<=n;++i)scanf("%lf",&W[i]);
    	scanf("%d",&S);scanf("%lf",&p);
        memset(f,0xfe,sizeof(f));
    	for(int i=1;i<=n;++i)f[0][i][i]=0;
    	for(int i=1;i<=m;++i)
    	{
    		int u=read(),v=read();
    		f[0][u][v]=W[v]*p;
    	}
    	for(int l=1;l<30;++l,p*=p)
    		for(int k=1;k<=n;++k)
    			for(int i=1;i<=n;++i)
    				for(int j=1;j<=n;++j)
    					f[l][i][j]=max(f[l][i][j],f[l-1][i][k]+p*f[l-1][k][j]);
    	for(int i=1;i<=n;++i)Ans=max(Ans,f[29][S][i]);
    	printf("%.1lf
    ",Ans+W[S]);
    	return 0;
    }
    
    
  • 相关阅读:
    ThinkPHP—URL的访问以及各种方法的操作
    深入理解line-height与vertical-align——前端布局常用属性
    深入理解display属性——前端布局常用重要属性
    使用JQuery实现图片轮播效果
    新手之首次部署阿里云centos7+mysql+asp.net mvc core应用之需要注意的地方
    NPOI 之导入导出
    Sqlserver 还原
    SQL Server数据库状态和文件状态
    Sqlserver 备份
    单例模式
  • 原文地址:https://www.cnblogs.com/cjyyb/p/9113837.html
Copyright © 2011-2022 走看看