TopCoder SRM620 DIV2

250  排序

根据所指定的关键字排序,如果关键字相同则更具输入顺序排序

500 搜索

// BEGIN CUT HERE

// END CUT HERE
#include <string>
#include <vector>
#include <algorithm>
#include <cstdio>
#include <iostream>
#include <map>
#include <utility>
#include <cmath>
#include <queue>
#include <stack>
#include <cstring>
#include <cstdlib>
#include <set>
#include <iterator>
#include <sstream>
#include <ctime>

using namespace std;

typedef long long LL;

#define sz(x) x.size()
#define pb push_back
#define mp make_pair
#define clr(x,a) memset(x,a,sizeof(x))
#define cpy(x,a) memcpy(x,a,sizeof(x))


class PairGameEasy {
	public:
    bool dfs(int x,int y,int a,int b){
        if(x>a) return false;
        if(y>b) return false;
        if(x==a && y==b) return true;
        if(dfs(x+y,y,a,b)) return true;
        if(dfs(x,y+x,a,b)) return true;
        return false;
    }
	string able(int a, int b, int c, int d) {
	    if(dfs(a,b,c,d))
            return "Able to generate";
        else
            return "Not able to generate";

	}


};
// BEGIN CUT HERE

// END CUT HERE


1000 概率dp(记忆化搜索)

求n个点,每两个点之间有一条边的概率是一个给定的值p

现在求生成的图 至少有四个点相连的概率是多少

反向思维,转化成没有4个点相连的情况下概率是多少。


首先我们将不存在至少四个点相连的情况称为不和法的状态

用f(r,a,b,c)表示剩余r个点加入到当前图中能够构成一张不合法的图的概率是多少。其中  a:表示孤立点数量为1 b:表示有两个点的联通分量数量 c:表示三个点的联通分量数量并且我们设 f(0,a,b,c)=1因为已经没有点需要加入到当前图中,且当前图是一个不合法的状态。


我们接下来要讨论在a,b,c的状态下加入一个点可以怎么加

1: 新加入的点单独作为一个孤立点 那么 我们可以得到状态 f(r-1,a+1,b,c)

在这一个过程中任何一个点都不会与新加入的点有边相连  那么 这种情况下概率为 (1-p)^(a+2b+3c)*p(r-1,a+1,b,c)

2:将新加入的点与之前的孤立点相连,构成一个新的大小为2的联通分量得到·状态f(r-1,a-1,b+1,c)

在这个过程中,之前在大小为2的和大小为3的联通分量重的点一定不会与新加入的点有边相连,在这种情况下概率为 (1-p)^(2b+3c)*p*(1-p)^(a-1)*f(r-1,a-1,b+1,c)*a

需要注意的是这种情况下,可以与新加入的点相连的点一共有a个,需要把所有概率累加起来

3:将新加入的点与两个之前是孤立点的点相连,构成一个新的大小为3的联通分量,得到状态f(r-1,a-2,b,c+1)

在这个过程中。大小为2的和大小为3的联通分量中的点一定不会与新加入的点有边相连,在这种情况下概率为 (1-p)^(2b+3c)*p*p*(1-p)^(a-2)*f(r-1,a-2,b,c+1)*a*(a-1)/2

需要注意的是在这种情况下我们要选取两个孤立点,在有a个孤立点的情况下,一共有a*(a-1)/2中选法,注意把所有情况累加

4:将新加入的点与之前大小为2的联通分量中的1个点相连,构成一个新的大小为3的联通分量,得到状态f(r,a,b-1,c+1)

在这种情况下孤立点与大小为3的联通分量中的点一定不会被选到,这种情况下的概率为(1-p)^(a+3c)*p*(1-p)^(2b-1)*f(r,a,b-1,c+1)*2*b

需要注意这种情况一共有2b中连边方法

5:将新加入的点与之前大小为2的联通分量中的2个点相连,构成一个新的大小为3的联通分量,得到状态f(r,a,b-1,c+1)

在这种情况下孤立点与大小为3的联通分量中的点一定不会被选到,这种情况下的概率为(1-p)^(a+3c)*p*(1-p)^(2b-2)*f(r,a,b-1,c+1)*b

需要注意这种情况一共有b中连边方法


最后状态f(r,a,b,c)的概率就是上述所有情况的累加


// BEGIN CUT HERE

// END CUT HERE
#include <string>
#include <vector>
#include <algorithm>
#include <cstdio>
#include <iostream>
#include <map>
#include <utility>
#include <cmath>
#include <queue>
#include <stack>
#include <cstring>
#include <cstdlib>
#include <set>
#include <iterator>
#include <sstream>
#include <ctime>

using namespace std;

typedef long long LL;

#define sz(x) x.size()
#define pb push_back
#define mp make_pair
#define clr(x,a) memset(x,a,sizeof(x))
#define cpy(x,a) memcpy(x,a,sizeof(x))


bool vis[55][30][20];
double dp[55][30][20];

double dfs(int r,int a,int b,int c,double p){
    if(vis[a][b][c])
        return dp[a][b][c];
    double ret=0;
    vis[a][b][c]=1;
    if(r==0)
        return dp[a][b][c]=1;
    int total=a+b*2+c*3;
    ret+=pow(1-p,total)*dfs(r-1,a+1,b,c,p);
    if(a>0)
        ret+=pow(1-p,total-a)*pow(1-p,a-1)*p*a*dfs(r-1,a-1,b+1,c,p);
    if(a>1)
        ret+=pow(1-p,total-a)*pow(1-p,a-2)*p*p*a*(a-1)/2*dfs(r-1,a-2,b,c+1,p);
    if(b>0){
        ret+=pow(1-p,total-2*b)*pow(1-p,2*b-1)*p*2*b*dfs(r-1,a,b-1,c+1,p);
        ret+=pow(1-p,total-2*b)*pow(1-p,2*b-2)*p*p*b*dfs(r-1,a,b-1,c+1,p);
    }
    return dp[a][b][c]=ret;
}

class RandomGraph {
	public:

	double probability(int n, int p) {
	    double prob=p*1.0/1000;
	    memset(vis,0,sizeof(vis));
	    return 1-dfs(n,0,0,0,prob);
	}

// END CUT HERE

};
// BEGIN CUT HERE
// END CUT HERE


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值