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;
    }
    
  • 相关阅读:
    [NOI2017]游戏
    [USACO09MAR]Cleaning Up
    [POI2010]Blocks
    [JSOI2011]分特产
    [POI2001]Peaceful Commission
    BZOJ4152 [AMPPZ2014]The Captain
    Luogu P3783 [SDOI2017]天才黑客
    Luogu P3645 [APIO2015]雅加达的摩天楼
    Luogu P1613 跑路
    AGC009E Eternal Average
  • 原文地址:https://www.cnblogs.com/shaokele/p/9374051.html
Copyright © 2011-2022 走看看