当前位置: 首页 > news >正文

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];
		}
	}
}

  

 

相关文章:

  • ssh-agent
  • 手机app有了短信验证码还有没必要有图片验证码?
  • 基于原型链劫持的前端代码插桩实践
  • Java动态代理机制——那些让你面试脱颖而出的技能 推荐
  • python正则表达式的使用
  • Nginx配置SSL实现服务器/客户端双向认证
  • reqeusts用法
  • 【总结整理】交互心理学---摘自《人人都是产品经理》
  • 智能情侣枕Pillow Talk,倾听彼此的心跳
  • 在线uml软件,在线思维导图软件
  • (原創) 博客園正式支援VHDL語法著色功能 (SOC) (VHDL)
  • 楚留香mv
  • TestDriven.NET和Visual Studio Express的纠纷往事
  • 19.分屏查看命令 more命令
  • A WebSite for MapXtreme Resource
  • JavaScript 如何正确处理 Unicode 编码问题!
  • ES10 特性的完整指南
  • EventListener原理
  • gf框架之分页模块(五) - 自定义分页
  • gitlab-ci配置详解(一)
  • IE报vuex requires a Promise polyfill in this browser问题解决
  • Linux下的乱码问题
  • miniui datagrid 的客户端分页解决方案 - CS结合
  • Python 基础起步 (十) 什么叫函数?
  • 关于Android中设置闹钟的相对比较完善的解决方案
  • ------- 计算机网络基础
  • 微信小程序上拉加载:onReachBottom详解+设置触发距离
  • ​​​​​​​​​​​​​​Γ函数
  • ​人工智能书单(数学基础篇)
  • #1015 : KMP算法
  • #mysql 8.0 踩坑日记
  • #我与Java虚拟机的故事#连载11: JVM学习之路
  • (+3)1.3敏捷宣言与敏捷过程的特点
  • (1) caustics\
  • (MonoGame从入门到放弃-1) MonoGame环境搭建
  • (zt)基于Facebook和Flash平台的应用架构解析
  • (附源码)php新闻发布平台 毕业设计 141646
  • (更新)A股上市公司华证ESG评级得分稳健性校验ESG得分年均值中位数(2009-2023年.12)
  • (九)c52学习之旅-定时器
  • (三)docker:Dockerfile构建容器运行jar包
  • (十)T检验-第一部分
  • (一)插入排序
  • (原創) 人會胖會瘦,都是自我要求的結果 (日記)
  • (转)eclipse内存溢出设置 -Xms212m -Xmx804m -XX:PermSize=250M -XX:MaxPermSize=356m
  • (转)Java socket中关闭IO流后,发生什么事?(以关闭输出流为例) .
  • .Family_物联网
  • .net 生成二级域名
  • .NET/C# 在代码中测量代码执行耗时的建议(比较系统性能计数器和系统时间)
  • .NET6实现破解Modbus poll点表配置文件
  • 。Net下Windows服务程序开发疑惑
  • @31省区市高考时间表来了,祝考试成功
  • @ModelAttribute 注解
  • @vue/cli脚手架
  • []error LNK2001: unresolved external symbol _m
  • [C#]winform制作仪表盘好用的表盘控件和使用方法