• JLOI2012:时间流逝


    Description

    生活可以很简单。可以探索水底世界的神秘,也可以去发现奇特新生物,亦或踏上一段新生的旅程。在必须要迎接挑战或跟周围的生物进行生存争夺之前,享受自由的飞翔。此时你会觉得生活是如此美好。
    像蛇喜欢吃浮游生物一样(哦,我好像忘记告诉你这个常识),每天,你可以吃一些你周围的基础生物,然后会在你的尾巴上得到一个能量圈。你将会有好多种不同的能量圈,每一个都会被赋予一个能量。你可以拥有多个同种的能量圈,但是对于新得到的相同的能量圈,它的能量不能大于你已拥有的任何一个能量圈。除了前面的规则,获得新的能量圈的种类的概率是一样的。一天天过去,你得到越来越多的能量,开始了进化演变。
    但是你也有自己的问题,有时你会面对邪恶的果冻鱼。它会追着你咬你,你不得不扔出最小能量值的能量圈然后赶忙逃跑。在这种情况下,你不会有任何的胃口了,因此这天你将不再得到任何能量圈。幸好,当你没有任何能量圈的时候,果冻鱼就算看见你也不会追着你,此时你可以好好地享用美食。
    你听说当你的总的能量值超过了某个阈值之后,可以进化成强大模式并能够吃掉果冻鱼。是时候反击了!下面是本题的问题:预计要过多少天你才能进化成强大模式?(第一天默认你没有任何能量圈)

    Solution

    状态数很少,是 (M) 的正整数划分,大约是 (10^6) 左右
    搜索出所有的状态,容易发现是一个树形结构
    有转移:
    (f[x]=1+p*f[fa]+frac{1}{|son|}*(1-p)*sum f[son])
    树上高斯消元一下就行了

    #include<bits/stdc++.h>
    using namespace std;
    typedef unsigned long long ll;
    const int N=55,M=2e6+10;
    double p;int m,n,a[N],ID=0;
    double k[M],b[M];
    inline int dfs(int x,int la,int fa,int sz){
    	if(x<0)return 0;
    	int u=++ID;
    	for(int i=la;i>=1;i--)dfs(x-a[i],i,u,la);
    	if(u>1){
    		double t=(fa==1?1:1-p);
    		k[fa]-=t*p/(sz*k[u]);
    		b[fa]+=b[u]*t/(sz*k[u]);
    	}
    	return u;
    }
    int main(){
    	freopen("pp.in","r",stdin);
    	freopen("pp.out","w",stdout);
    	while(cin>>p>>m>>n){
    		ID=0;
    		for(int i=1;i<=n;i++)cin>>a[i];
    		for(int i=0;i<M;i++)k[i]=1,b[i]=1;
    		sort(a+1,a+n+1);
    		dfs(m,n,0,0);
    		b[1]=b[1]/k[1];
    		printf("%.3lf
    ",b[1]);
    	}
    	return 0;
    }
    
    
  • 相关阅读:
    #考研碎碎念#
    #考研笔记#计算机之病毒
    #考研笔记#计算机之多媒体应用
    #考研笔记#计算机之PPT问题
    第六章深入理解类
    第五章方法
    类的基本教程
    类型存储变量
    C#和.net框架
    C#编程概述
  • 原文地址:https://www.cnblogs.com/Yuzao/p/8961225.html
Copyright © 2020-2023  润新知