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