problem1 link

设$f[i][j]$表示已经分配了answers中的前$i$个,分配给的问题的状态为 $j$的方案数。

其中状态可以用$n$位的三进制表示,0表示还未分配,1表示已分配是 Yes,2表示已分配是No.

problem2 link

假设$n$个城市为[0,n-1]。设$f[i][j][t]$表示在[0,i]个城市中已经选择了$j$个城市,选择了$t$个人的概率。

那么选择第$i+1$个城市的概率是$\frac{k-j}{n-i-1}$.

problem3 link

首先,如果一个连通图中存在两个环,也就是有$n$个顶点,$n+1$条边,那么从其中一个环上的某一点(这一点不属于另外一个环)到另一个环上的某一点(同样这一点也不属于前一个环)会有超过两条简单路径。所以满足条件的连通图要么是树,要么是只有一个环(也就是树上多一条边)。

假设给出的边使得$n$个顶点分成了$m$个连通分量,第$i$个连通分量中点的个数是$v_{i}$。

(1)假设最后是一棵树(前提是$m$个连通分量中每个连通分量中都没有环)。最后的答案是$T(m)=n^{m-2}\prod_{i=1}^{m}v_{i}$.这里要用到prufer编码。对于$m$个联通块的树,其prufer编码的长度为$m-2$。每个位置有$n$种情况,最后乘以叶子节点可以连出的边的数量。

比如$m=3,n=4$,分别是1-2,3,4。那么长度为1的prufer编码可以是{1},{2},{3},{4}.(推导过程参看上面的链接)

对于{1}来说,有两种:第一种: 1-3,1-4, 第二种1-3,2-4

对于{2}来说,有两种:第一种: 2-3,2-4, 第二种2-3,1-4

对于{3}来说,有两种:第一种: 3-1,3-4, 第二种3-2,3-4

对于{4}来说,有两种:第一种: 4-1,4-3, 第二种4-2,4-3

(2)有一个环。那么就要看这个环连通了$m$个联通块中的几个。

第一种: 1个,那么只需要枚举是第几个联通块;

第二种:2个,假设是联通块$a,b$.那么就是$C_{v_av_b}^{2}$

第三种:大于等于3个,假设是$k$个,那么是$\frac{(k-1)!}{2}\prod_{i=1}^{k}v_{ci}^{2}$,其中$ci$第第$i$个选出的联通块的编号。这里除以2是因为有翻转导致重复的情况。比如$k=4$时,$abcd$和$dcab$是一样的。

最后将连成的环看做一个连通分量,那么最后还有$m-k+1$个连通分量,将其连成一个树的方案为$T(m-k+1)$。

code for problem1

import java.util.*;
import java.math.*;
import static java.lang.Math.*; public class TheQuestionsAndAnswersDivOne { public int find(int n, String[] answers) { int[] p = new int[n + 2];
p[0] = 1;
for (int i = 1; i < p.length; ++ i) {
p[i] = p[i - 1] * 3;
} int[][] f = new int[answers.length][p[n]];
for (int i = 0; i < n; ++ i) {
int t = answers[0].equals("No")? 1 : 2;
f[0][t * p[i]] = 1;
}
for (int i = 1; i < answers.length; ++ i) {
int t = answers[i].equals("No")? 1 : 2;
for (int k = 0; k < p[n]; ++ k) {
if (f[i - 1][k] == 0) {
continue;
}
for (int j = 0; j < n; ++ j) {
int x = k / p[j] % 3;
if (x == 0 || x == t) {
int nk = k;
if (x == 0) {
nk += t * p[j];
}
f[i][nk] += f[i - 1][k];
}
}
}
}
int result = 0;
for (int i = 0; i < p[n]; ++ i) {
boolean tag = true;
for (int j = 0; j < n; ++ j) {
if (i / p[j] % 3 == 0) {
tag = false;
break;
}
}
if (tag) {
result += f[answers.length - 1][i];
}
}
return result;
}
}

  

code for problem2

import java.util.*;
import java.math.*;
import static java.lang.Math.*; public class TheFansAndMeetingsDivOne { public double find(int[] minJ, int[] maxJ, int[] minB, int[] maxB, int k) {
final int n = minJ.length;
int s1 = 0, s2 = 0;
for (int i = 0; i < n; ++ i) {
s1 += maxJ[i];
s2 += maxB[i];
}
final int m = Math.min(s1, s2) + 1;
double[][][] f = new double[n][k + 1][m];
double[][][] g = new double[n][k + 1][m]; f[0][0][0] = 1 - 1.0 * k / n;
for (int i = minJ[0]; i <= maxJ[0] && i < m; ++ i) {
f[0][1][i] = 1.0 * k / n / (maxJ[0] - minJ[0] + 1);
}
g[0][0][0] = 1 - 1.0 * k / n;
for (int i = minB[0]; i <= maxB[0] && i < m; ++ i) {
g[0][1][i] = 1.0 * k / n / (maxB[0] - minB[0] + 1);
} for (int i = 1; i < n; ++ i) {
for (int j = 0; j <= i && j <= k; ++ j) {
final double p = 1.0 * (k - j) / (n - i);
final double p1 = p / (maxJ[i] - minJ[i] + 1);
final double p2 = p / (maxB[i] - minB[i] + 1);
for (int t = 0; t < m; ++ t) {
f[i][j][t] += f[i - 1][j][t] * (1 - p);
g[i][j][t] += g[i - 1][j][t] * (1 - p);
if (j == k) {
continue;
}
for (int x = minJ[i]; x <= maxJ[i] && x + t < m; ++ x) {
f[i][j + 1][x + t] += f[i - 1][j][t] * p1;
}
for (int x = minB[i]; x <= maxB[i] && x + t < m; ++ x) {
g[i][j + 1][x + t] += g[i - 1][j][t] * p2;
}
}
}
} double result = 0;
for (int i = 0; i < m; ++ i) {
result += f[n - 1][k][i] * g[n - 1][k][i];
}
return result;
}
}

  

code for problem3

import java.util.*;
import java.math.*;
import static java.lang.Math.*; public class TheCitiesAndRoadsDivOne { static final int MOD = 1234567891; public int find(String[] map) {
final int n = map.length;
UnionSet unionSet = new UnionSet(n);
for (int i = 0; i < n; ++ i) {
for (int j = i + 1; j < n; ++ j) {
if (map[i].charAt(j) == 'Y') {
unionSet.merge(i, j);
}
}
}
List<Integer> list = new ArrayList<>();
int m = 0;
int circleNum = 0;
for (int i = 0; i < n; ++ i) {
if (unionSet.get(i) == i) {
++ m;
list.add(unionSet.vertexNum[i]);
circleNum += unionSet.edges[i] - unionSet.vertexNum[i] + 1;
}
}
if (circleNum > 1) {
return 0;
} if (m == 1) {
if (circleNum == 1 || list.get(0) <= 2) {
return 1;
}
return list.get(0) * (list.get(0) - 1) / 2 - (list.get(0) - 1) + 1;
} long[] p = new long[n + 1];
p[0] = 1;
for (int i = 1; i <= n; ++ i) {
p[i] = p[i-1] * n % MOD;
}
long result = p[m - 2];
for (int i = 0; i < m; ++ i) {
result = result * list.get(i) % MOD;
}
if (circleNum == 1) {
return (int)result;
} int sum = 0;
for (int i = 0; i < m; ++ i) {
int t = list.get(i);
sum += t * (t - 1) / 2 - (t - 1);
}
result = result * (sum + 1) % MOD; for (int i = 0; i < (1 << m); ++ i) {
int cnt = 0;
for (int j = 0; j < m; ++ j) {
if ((i & (1 << j)) != 0) {
++ cnt;
}
}
if (cnt < 2) {
continue;
}
long tmp = 1;
if (cnt == 2) {
for (int j = 0; j < m; ++ j) {
if ((i & (1 << j)) != 0) {
tmp *= list.get(j);
}
}
tmp = tmp * (tmp - 1) / 2;
}
else {
for (int j = 3; j <= cnt - 1; ++ j) {
tmp = tmp * j % MOD;
}
for (int j = 0; j < m; ++ j) {
if ((i & (1 << j)) != 0) {
tmp = tmp * list.get(j) * list.get(j) % MOD;
}
}
}
if (cnt == m) {
result = (result + tmp) % MOD;
continue;
}
tmp = tmp * p[(m - cnt + 1) - 2] % MOD;
long totVertex = 0;
for (int j = 0; j < m; ++ j) {
if ((i & (1 << j)) != 0) {
totVertex += list.get(j);
}
else {
tmp = tmp * list.get(j) % MOD;
}
}
tmp = tmp * totVertex % MOD;
result = (result + tmp) % MOD;
}
return (int)result;
} static class UnionSet {
int[] father = null;
int[] edges = null;
int[] vertexNum = null; UnionSet(int n) {
father = new int[n];
edges = new int[n];
vertexNum = new int[n];
for (int i = 0; i < n; ++ i) {
father[i] = i;
edges[i] = 0;
vertexNum[i] = 1;
}
} int get(int u) {
if (father[u] == u) {
return u;
}
return father[u] = get(father[u]);
} void merge(int u, int v) {
int fu = get(u);
int fv = get(v);
++ edges[fu];
if (fu == fv) {
return;
}
father[fv] = fu;
vertexNum[fu] += vertexNum[fv];
edges[fu] += edges[fv];
}
}
}

  

topcoder srm 460 div1的更多相关文章

  1. Topcoder SRM 643 Div1 250<peter_pan>

    Topcoder SRM 643 Div1 250 Problem 给一个整数N,再给一个vector<long long>v; N可以表示成若干个素数的乘积,N=p0*p1*p2*... ...

  2. Topcoder Srm 726 Div1 Hard

    Topcoder Srm 726 Div1 Hard 解题思路: 问题可以看做一个二分图,左边一个点向右边一段区间连边,匹配了左边一个点就能获得对应的权值,最大化所得到的权值的和. 然后可以证明一个结 ...

  3. topcoder srm 714 div1

    problem1 link 倒着想.每次添加一个右括号再添加一个左括号,直到还原.那么每次的右括号的选择范围为当前左括号后面的右括号减去后面已经使用的右括号. problem2 link 令$h(x) ...

  4. topcoder srm 738 div1 FindThePerfectTriangle(枚举)

    Problem Statement      You are given the ints perimeter and area. Your task is to find a triangle wi ...

  5. Topcoder SRM 602 div1题解

    打卡- Easy(250pts): 题目大意:rating2200及以上和2200以下的颜色是不一样的(我就是属于那个颜色比较菜的),有个人初始rating为X,然后每一场比赛他的rating如果增加 ...

  6. Topcoder SRM 627 div1 HappyLettersDiv1 : 字符串

    Problem Statement      The Happy Letter game is played as follows: At the beginning, several players ...

  7. Topcoder SRM 584 DIV1 600

    思路太繁琐了 ,实在不想解释了 代码: #include<iostream> #include<cstdio> #include<string> #include& ...

  8. TopCoder SRM 605 DIV1

    604的题解还没有写出来呢.先上605的. 代码去practice房间找. 说思路. A: 贪心,对于每个类型的正值求和,如果没有正值就取最大值,按着求出的值排序,枚举选多少个类型. B: 很明显是d ...

  9. topcoder srm 575 div1

    problem1 link 如果$k$是先手必胜那么$f(k)=1$否则$f(k)=0$ 通过对前面小的数字的计算可以发现:(1)$f(2k+1)=0$,(2)$f(2^{2k+1})=0$,(3)其 ...

随机推荐

  1. struts2实现XML异步交互

    异步交互,在不用重新提交整个页面的情况下可以实现页面局部信息与服务器的交互.在编写异步交互时需要用到一个架包:dom4j,下载地址为:https://dom4j.github.io/ 下面通过例子说明 ...

  2. node.js中express模块创建服务器和http模块客户端发请求

    首先下载express模块,命令行输入 npm install express 1.node.js中express模块创建服务端 在js代码同文件位置新建一个文件夹(www_root),里面存放网页文 ...

  3. Rpgmakermv(18)GALV RollCredits

    原文: Galv's Roll Credits ---------------------------------------------------------------------------- ...

  4. UML之状态机图

    状态机图 基本概念: 状态机图,UML 1.x规范中称状态图,是一个展示状态机的图. 状态机图基本上就是一个状态机中元素的投影,这也就意味着状态机图包括状态机的所有特征.状态机图显示了一个对象如何根据 ...

  5. php aes128加密

    //[加密数据]AES 128 ECB模式 public function aesEncrypt($str){ $screct_key = Yii::$app->params['encryptK ...

  6. 即时通信系统中实现全局系统通知,并与Web后台集成【附C#开源即时通讯系统(支持广域网)——QQ高仿版IM最新源码】

    像QQ这样的即时通信软件,时不时就会从桌面的右下角弹出一个小窗口,或是显示一个广告.或是一个新闻.或是一个公告等.在这里,我们将其统称为“全局系统通知”.很多使用C#开源即时通讯系统——GGTalk的 ...

  7. SourceTree 使用

    删除分支 新建一个分支 A 后,要想把 A 分支删除掉,只需跳到另一个分支上去,选中 A 分支然后右击,在弹出的菜单栏中选中 [删除 A 分支]即可: 在分支下建一个文件夹 左上的然后弹出选框,在[新 ...

  8. Spring源码阅读(一)

    Spring通过配置文件或者注解对类实例进行加载管理.稍微思考,可以猜测spring加载过程肯定先把配置转化为统一的配置对象,再把通过配置对象生产类实例.阅读源码,我们也可以发现这个逻辑. sprin ...

  9. linux dns

    linux 用户相关的 root   相当于QQ群主 sudo  QQ群管理员 普通用户  QQ群水军 root  UID 是 0   组UID也是0  普通用户UID从1000开始 查看用户id 信 ...

  10. 查询在某一个时间段内的sql(oracel)

    ( to_char(t.TUIJIAN_TIME, 'yyyy-MM-dd') between   #{begin_time}   and #{end_time} )