zoukankan      html  css  js  c++  java
  • bzoj2306: [Ctsc2011]幸福路径(倍增+Floyed 逼近答案)

    www.cnblogs.com/shaokele/


    bzoj2306: [Ctsc2011]幸福路径##

      Time Limit: 10 Sec
      Memory Limit: 256 MB

    Description###

      有向图 G有n个顶点 1, 2, …, n,点i 的权值为 w(i)。现在有一只蚂蚁,从给定的起点 v0出发,沿着图 G 的边爬行。开始时,它的体力为 1。每爬过一条边,它的体力都会下降为原来的 ρ 倍,其中ρ 是一个给定的小于1的正常数。而蚂蚁爬到某个顶点时的幸福度,是它当时的体力与该点权值的乘积。
      我们把蚂蚁在爬行路径上幸福度的总和记为 H。很显然,对于不同的爬行路径,H 的值也可能不同。小 Z 对 H 值的最大可能值很感兴趣,你能帮助他计算吗?注意,蚂蚁爬行的路径长度可能是无穷的。
     

    Input###

      每一行中两个数之间用一个空格隔开。
      输入文件第一行包含两个正整数 n, m,分别表示 G 中顶点的个数和边的条数。
      第二行包含 n个非负实数,依次表示 n个顶点权值 w(1), w(2), …, w(n)。
      第三行包含一个正整数 v0,表示给定的起点。
      第四行包含一个实数 ρ,表示给定的小于 1的正常数。
      接下来 m行,每行两个正整数 x, y,表示<x, y>是G的一条有向边。可能有自环,但不会有重边。
     

    Output###

       仅包含一个实数,即 H值的最大可能值,四舍五入到小数点后一位。
     

    Sample Input###

      5 5
      
      10.0 8.0 8.0 8.0 15.0
      
      1
      
      0.5
      
      1 2
      
      2 3
      
      3 4
      
      4 2
      
      4 5
      

    Sample Output###

      18.0
      

    HINT###

      对于 100%的数据, n ≤ 100, m ≤ 1000, ρ ≤ 1 – 10^-6, w(i) ≤ 100 (i = 1, 2, …, n)。
      

    题目地址:  bzoj2306: [Ctsc2011]幸福路径

    题目大意:

      给定⼀张有向图,每个点有个权值,蚂蚁从某个点开始,初始体⼒为1,每经过⼀条边,体⼒会变为原来的p(0<p<1)倍,每爬到⼀个点,获得的幸福度为该点的权值乘上体⼒。求蚂蚁幸福度的最⼤值,保留⼀位⼩数。

    题解:

      考虑到体力衰减很快,所以我们只要做有限次数的如下 (dp) 即可
       (f[t][i][j]) 表示⾛ (2^t) 步,从 (i) ⾛到 (j) 获得的最⼤幸福度。
      $$f[t][i][j]=max(f[t-1][i][k]+f[t-1][k][j]*p{2{t-1}})$$
       (t) ⾜够⼤时, (f) 得到的就近似为最⼤的幸福值。
      或者说当 (p<eps) 时,得到的就近似为最⼤的幸福值。


    AC代码

    #include <cstdio> 
    #include <cstring>
    #include <algorithm>
    using namespace std;
    const int N=105;
    int n,m,S;
    double p,ans=0,val[N],f[N][N],g[N][N];
    int main(){
    	scanf("%d%d",&n,&m);
    	for(int i=1;i<=n;i++)
    		scanf("%lf",&val[i]);
    	scanf("%d",&S);
    	scanf("%lf",&p);
    	for(int i=1;i<=n;i++)
    		for(int j=1;j<=n;j++)
    			if(i!=j)f[i][j]=-1e100;
    	while(m--){
    		int u,v;
    		scanf("%d%d",&u,&v);
    		f[u][v]=val[v]*p;
    	}
    	for(;p>1e-10;p*=p){
    		for(int i=1;i<=n;i++)
    			for(int j=1;j<=n;j++)
    				g[i][j]=-1e100;
    		for(int k=1;k<=n;k++)
    			for(int i=1;i<=n;i++)
    				for(int j=1;j<=n;j++)
    					g[i][j]=max(g[i][j],f[i][k]+f[k][j]*p);
    		memcpy(f,g,sizeof(g));
    	}
    	for(int i=1;i<=n;i++)
    		ans=max(ans,f[S][i]);
    	printf("%.1f
    ",ans+val[S]);
    	return 0;
    }
    
  • 相关阅读:
    创建Variant数组
    ASP与存储过程(Stored Procedures)
    FileSystemObject对象成员概要
    Kotlin 朱涛9 委托 代理 懒加载 Delegate
    Kotlin 朱涛 思维4 空安全思维 平台类型 非空断言
    Kotlin 朱涛7 高阶函数 函数类型 Lambda SAM
    Kotlin 朱涛16 协程 生命周期 Job 结构化并发
    Proxy 代理模式 动态代理 cglib MD
    RxJava 设计理念 观察者模式 Observable lambdas MD
    动态图片 Movie androidgifdrawable GifView
  • 原文地址:https://www.cnblogs.com/shaokele/p/9374051.html
Copyright © 2011-2022 走看看