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)其 ...
随机推荐
- oracle 常用(二)
多表查询: 1.等值连接查询: select a.aa,a.bb,b.qq from XX a , CC b where a.aa= b.ee 2.不等值连接: select * fr ...
- vue-lazyload的使用
1.下载依赖 npm install vue-lazyload --save 2.引入 import Vue from 'vue' import App from '@/App' import Vue ...
- Uncaught DOMException: Blocked a frame with origin "http://localhost
ajaxFileUpload上传时报错 :Uncaught DOMException: Blocked a frame with origin "http://localhost..... ...
- TP5数据库操作方法
一.TP5数据库操作方法 1.name()方法作用 : 指定默认的数据表名(不含前缀)示例 : Db::name(‘weiba_post’);返回 : Db对象 2.setTable()方法作用 : ...
- LeetCode83.删除排序链表中的重复的元素
给定一个排序链表,删除所有重复的元素,使得每个元素只出现一次. 示例 1: 输入: 1->1->2 输出: 1->2 示例 2: 输入: 1->1->2->3-&g ...
- [15]Windows内核情景分析 --- 权限管理
Windows系统是支持多用户的.每个文件可以设置一个访问控制表(即ACL),在ACL中规定每个用户.每个组对该文件的访问权限.不过,只有Ntfs文件系统中的文件才支持ACL. (Ntfs文件系统中, ...
- 详解tween.js 中文使用指南
补间(动画)是一个概念,允许你以平滑的方式更改对象的属性.你只需告诉它哪些属性要更改,当补间结束运行时它们应该具有哪些最终值,以及这需要多长时间,补间引擎将负责计算从起始点到结束点的值. 例如,pos ...
- 【2017-03-02】C#集合,结构体,枚举
集合 集合与数组的区别 数组:同一类型,固定长度 集合:不同类型,不固定长度 使用集合前需要: 引用命名空间:using System.Collections; 1.普通集合 定义: Arra ...
- Linux环境变量和本地变量
每一种编程语言中,我们都会碰到变量的作用域的问题.(比如在函数中定义的变量在函数外不能使用的) BASH 中也有类似的问题,局部变量和环境变量(全局变量). 局部变量是普通的变量,仅在创建它的Shel ...
- LCA 最近公共祖先 (模板)
#include <iostream> #include <stdio.h> #include <cstring> #include <vector> ...