topcoder srm 460 div1
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的更多相关文章
- Topcoder SRM 643 Div1 250<peter_pan>
Topcoder SRM 643 Div1 250 Problem 给一个整数N,再给一个vector<long long>v; N可以表示成若干个素数的乘积,N=p0*p1*p2*... ...
- Topcoder Srm 726 Div1 Hard
Topcoder Srm 726 Div1 Hard 解题思路: 问题可以看做一个二分图,左边一个点向右边一段区间连边,匹配了左边一个点就能获得对应的权值,最大化所得到的权值的和. 然后可以证明一个结 ...
- topcoder srm 714 div1
problem1 link 倒着想.每次添加一个右括号再添加一个左括号,直到还原.那么每次的右括号的选择范围为当前左括号后面的右括号减去后面已经使用的右括号. problem2 link 令$h(x) ...
- topcoder srm 738 div1 FindThePerfectTriangle(枚举)
Problem Statement You are given the ints perimeter and area. Your task is to find a triangle wi ...
- Topcoder SRM 602 div1题解
打卡- Easy(250pts): 题目大意:rating2200及以上和2200以下的颜色是不一样的(我就是属于那个颜色比较菜的),有个人初始rating为X,然后每一场比赛他的rating如果增加 ...
- Topcoder SRM 627 div1 HappyLettersDiv1 : 字符串
Problem Statement The Happy Letter game is played as follows: At the beginning, several players ...
- Topcoder SRM 584 DIV1 600
思路太繁琐了 ,实在不想解释了 代码: #include<iostream> #include<cstdio> #include<string> #include& ...
- TopCoder SRM 605 DIV1
604的题解还没有写出来呢.先上605的. 代码去practice房间找. 说思路. A: 贪心,对于每个类型的正值求和,如果没有正值就取最大值,按着求出的值排序,枚举选多少个类型. B: 很明显是d ...
- 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)其 ...
随机推荐
- vuex使用一
至于为什么使用vuex在这里就不过多的解释了,直接进入正题 1.vuex的安装 cnpm install vuex -S 2.然后在main.js中引入 import Vue from 'vue' i ...
- Tomcat任意文件上传漏洞CVE-2017-12615
文章来源:https://blog.csdn.net/qq1124794084/article/details/78044756 漏洞影响的tomcat版本为tomcat7.0.0-7.0.81版本 ...
- HDU 2842 Chinese Rings(常数矩阵)
Chinese Rings 转载自:点这里 [题目链接]Chinese Rings [题目类型]常数矩阵 &题意: 一种中国环,解开第k个环需要先解开全部的前(k-2)个环,并留有第(k-1) ...
- VS2010和选中代码相同的代码的颜色设置,修改高亮颜色
使用Visual Studio 2010, 发现很难看清非活动的选中代码,研究了下,发现以下方法可以设置: 1. 菜单:工具 -> 选项 ->环境 ->字体和颜色 2. 在右边 ...
- c# 集合中有数字、字符的Orderby排序
string[] things= new string[] { "105", "101", "102", "103", ...
- db2修改表结构,增加列,删除列等
增加一列:ALTER TABLE tbname ADD COLUMN columnName datatype; 增加多列:ALTER TABLE tbname ADD COLUMN columnNam ...
- [ Deep Learning ] Keras & TensorFlow安装依赖包
OS:Mac Python:3.6 一.先安装Keras,再安装TensorFlow 1. 安装Keras Package Version---------- -------h5py 2.7.1 Ke ...
- Day10 Python网络编程 Socket编程
一.客户端/服务器架构 1.C/S架构,包括: 1.硬件C/S架构(打印机) 2.软件C/S架构(web服务)[QQ,SSH,MySQL,FTP] 2.C/S架构与socket的关系: 我们学习soc ...
- Vue系列之 => 列表动画
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- html5-table布局
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8&qu ...