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. keepalived+双主架构

    简介 keepalived是基于VRRP协议的,全称 Virtual Redundent Routing Protocal 虚拟路由协议,为解决静态路由单点故障引起的网络失效问题设计的一套主备协议 两 ...

  2. HDU 4565 So Easy(矩阵解公式)

    So Easy [题目链接]So Easy [题目类型]矩阵解公式 &题解: 感觉这种类型的题都是一个套路,这题和hdu 2256就几乎是一样的. 所以最后2Xn就是答案 [时间复杂度]\(O ...

  3. awk命令学习(1)

    awk是一个强大的文本分析工具,相对于grep的查找,sed的编辑,awk在其对数据分析并生成报告时,显得尤为强大.简单来说awk就是把文件逐行的读入,以空格为默认分隔符将每行切片,切开的部分再进行各 ...

  4. Mybatis Generator 使用com.mysql.cj.jdbc.Driver遇到的问题

    Mybatis Generator 使用com.mysql.cj.jdbc.Driver遇到的问题 今天闲来无事,准备搭一套SSM的环境,当然所有的jar包都用最新的. Mybatis使用3.4.6, ...

  5. yii2 modules模块配置指南

    在Yii2 中模块是可以无限级嵌套的,也就是说,模块可以包含另一个包含模块的模块,我们称前者为父模块,后者为子模块, 子模块必须在父模块的yiibaseModule::modules属性中申明,例如: ...

  6. C#操作XML方法详解

    using System.Xml; //初始化一个xml实例 XmlDocument xml=new XmlDocument();   //导入指定xml文件 xml.Load(path); xml. ...

  7. uvalive 3276 The Great Wall Game

    题意: 一个n * n的棋盘上放着n个棋子,现在要求把这n个棋子用最少的步数移到同一条直线上,即同一列同一行或者同一对角线(两条).输出最少的步数(只能往四个方向移动,即正东,正西,正南,正北). 思 ...

  8. 基于TCP/IP协议的socket通讯client

    package com.ra.car.utils; import java.io.BufferedReader; import java.io.IOException; import java.io. ...

  9. 参与.net开源项目开发

    EntityFramework6 https://github.com/aspnet/EntityFramework6 https://github.com/aspnet/EntityFramewor ...

  10. Spark学习之路 (六)Spark Transformation和Action

    Transformation算子 基本的初始化 java static SparkConf conf = null; static JavaSparkContext sc = null; static ...