problem1 link

以两个点$p,q$为中心的两个正方形的边长和最大为$2dist(p,q)$,即$p,q$距离的两倍。

也就是两个$p,q$的连线垂直穿过两个正方形的一对边且平分两个正方形。

problem2 link

简化一下题意就是每个base和每个plant都有一个代价。要么付出某个base的代价,要么付出其对应的plant的代价。

将base和plant建立网络流。

源点到每个plant的边的流量为其代价

base到汇点的边的流量为其代价

base与其对应plant的边的流量为无穷大。

然后求最小割即可。

割到的plant就说明要付出这个plant的代价,割到的base就说明付出这个base的代价。

problem3 link

令$p=\frac{1}{d},q=\frac{d-1}{d}$

在$[n-d,n-1]$中任意一个格子,其一步到达$n$的概率都是$p$。恰好经过$t$步到达$n$的概率为$pq^{t-1}$

设$p1[i]$表示先手恰好经过$i$步第一次进入$[n-d,n-1]$区间的概率;

设$p2[i]$表示后手恰好经过$i$步第一次进入$[n-d,n-1]$区间的概率;

设$g(i,j)$表示先手、后手分别经过$i,j$步到达$[n-d,n-1]$区间且先手胜利的概率。

$g(i,j)$的计算方法为:

===============================

g(i,j)=0

if(i<j) {

$g(i,j) += p1[i]*p2[j]*(1-q^{j-i})$  //在后手未进入最后区间时取得胜利

}

$g(i,j)+=p1[i]*p2[j] * q^{|i-j|} * \frac{d}{d+d-1}$  //都进入最后区间再经过若干轮角逐后取得胜利

===============================

那么答案为所有的$g(i,j)$之和。

code for problem1

import java.util.*;
import java.math.*;
import static java.lang.Math.*; public class TurretPlacement { public long count(int[] x, int[] y) {
long result = 0;
for (int i = 0; i < x.length; ++ i) {
for (int j = i + 1; j < x.length; ++ j) {
result += cal(x[i], y[i], x[j], y[j]);
}
}
return result;
}
long cal(int x1, int y1, int x2, int y2) {
long d = (long)(Math.sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2)) * 2);
return d * (d - 1) / 2;
}
}

  

code for problem2

import java.util.*;
import java.math.*;
import static java.lang.Math.*; class MaxFlow {
static class node
{
int v,cap,next;
}; List<node> edges = null;
int[] head = null;
int vertexNum;
int[] pre = null;
int[] cur = null;
int[] num = null;
int[] h = null; public MaxFlow(int vertexNum) {
this.vertexNum = vertexNum;
edges = new ArrayList<>();
head = new int[vertexNum];
Arrays.fill(head, -1);
pre = new int[vertexNum];
cur = new int[vertexNum];
num = new int[vertexNum];
h = new int[vertexNum];
} private void addEdge(int u, int v, int cap)
{
node p = new node();
p.v = v;
p.cap = cap;
p.next = head[u];
head[u] = edges.size();
edges.add(p);
} public void add(int u, int v, int cap)
{
addEdge(u, v, cap);
addEdge(v, u,0);
} public int getMaxflow(int source, int sink)
{
for (int i = 0; i < vertexNum; ++ i) {
cur[i] = head[i];
num[i] = 0;
h[i] = 0;
}
int u = source;
int result = 0;
while (h[u] < vertexNum)
{
if (u == sink)
{
int Min=Integer.MAX_VALUE;
int v = -1;
for (int i = source; i != sink; i = edges.get(cur[i]).v)
{
int k=cur[i];
if(edges.get(k).cap < Min) {
Min = edges.get(k).cap;
v = i;
}
}
result += Min;
u=v;
for (int i = source; i != sink; i = edges.get(cur[i]).v)
{
int k=cur[i];
edges.get(k).cap -= Min;
edges.get(k ^ 1).cap += Min;
}
}
int index = -1;
for (int i = cur[u]; i != -1; i = edges.get(i).next)
{
if (edges.get(i).cap > 0 && h[u] == h[edges.get(i).v] + 1) {
index = i;
break;
}
}
if (index != -1)
{
cur[u] = index;
pre[edges.get(index).v]=u;
u=edges.get(index).v;
}
else
{
if (--num[h[u]] == 0) {
break;
}
int k = vertexNum;
cur[u] = head[u];
for (int i = head[u]; i != -1; i = edges.get(i).next)
{
if(edges.get(i).cap>0 && h[edges.get(i).v] < k)
{
k = h[edges.get(i).v];
}
}
if (k + 1 < vertexNum) {
num[k + 1] += 1;
}
h[u] = k + 1;
if (u != source) u=pre[u];
}
}
return result;
}
} public class GreenWarfare { int p2(int x) {
return x * x;
} public int minimumEnergyCost(int[] canonX, int[] canonY, int[] baseX, int[] baseY,
int[] plantX, int[] plantY, int energySupplyRadius) {
final int n = baseX.length;
final int m = plantX.length;
MaxFlow maxFlow = new MaxFlow(n + m + 2);
for (int j = 0; j < m; ++ j) {
int c = Integer.MAX_VALUE;
for (int i = 0; i < canonX.length; ++ i) {
c = Math.min(c, p2(canonX[i] - plantX[j]) + p2(canonY[i] - plantY[j]));
}
maxFlow.add(0, j + 1, c);
}
for (int j = 0; j < n; ++ j) {
int c = Integer.MAX_VALUE;
for (int i = 0; i < canonX.length; ++ i) {
c = Math.min(c, p2(canonX[i] - baseX[j]) + p2(canonY[i] - baseY[j]));
}
maxFlow.add(m + j + 1, m + n + 1, c);
}
for (int i = 0; i < m; ++ i) {
for (int j = 0; j < n; ++ j) {
int d = p2(baseX[j] - plantX[i]) + p2(baseY[j] - plantY[i]);
if ( d <= p2(energySupplyRadius)) {
maxFlow.add(i + 1, m + j + 1, Integer.MAX_VALUE);
}
}
}
return maxFlow.getMaxflow(0, m + n + 1);
}
}

  

code for problem3

import java.util.*;
import java.math.*;
import static java.lang.Math.*; public class BouncingDiceGame { public double winProbability(int n, int d, int x, int y) {
double[] p1 = cal(n, d, x);
double[] p2 = cal(n, d, y);
double[] p = new double[n];
p[0] = 1;
p[1] = (d - 1.0) / d;
for (int i = 2; i < n; ++ i) {
p[i] = p[i - 1] * p[1];
}
double result = 0;
for (int i = 0; i < p1.length; ++ i) {
for (int j = 0; j < p2.length; ++ j) {
if (i < j) {
result += p1[i] * p2[j] * (1 - p[j - i]);
}
result += p1[i] * p2[j] * p[Math.abs(i - j)] * d / (d + d - 1);
}
}
return result;
}
double[] cal(int n, int d, int x) {
if (x >= n - d) {
double[] result = new double[1];
result[0] = 1;
return result;
}
final int m = n - d - x;
double[] result = new double[m + 1];
result[0] = 0;
double[][] f = new double[2][n];
for (int i = x; i <n; ++ i) {
f[0][i] = 1;
}
int pre = 0;
int cur = 1;
for (int i = 1; i <= m; ++ i) {
Arrays.fill(f[cur], 0);
for (int j = x + 1; j < n; ++ j) {
int rr = j - 1 >= n - d? n - d - 1 : j - 1;
int ll = j - d - 1 >= 0? j - d - 1: 0;
if (rr < ll) {
continue;
}
f[cur][j] = (f[pre][rr] - f[pre][ll] ) / d;
}
for (int j = x; j < n; ++ j) {
f[cur][j] += f[cur][j - 1];
}
result[i] = f[cur][n - 1] - f[cur][n - d - 1];
pre ^= 1;
cur ^= 1;
}
return result;
}
}

  

topcoder srm 465 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. Nodejs【单机】多进程模式集群

    Nodejs[单机]多进程模式集群实例: 1.安装:npm install -s cluster 2.服务代码: var debug = require('debug'); var express = ...

  2. caffe在Linux下生成均值文件

    参照博客:https://blog.csdn.net/sinat_28519535/article/details/78533319

  3. SQLSetStmtAttr

    SQLSetStmtAttr 函数定义: Stmt是用来执行SQL语句的句柄,这个函数是用来设置她的属性的 SQLRETURN SQLSetStmtAttr( SQLHSTMT     , 这是由游标 ...

  4. Nginx技术研究系列3-OpenResty安装配置

    上两篇中介绍了: Ngnix技术研究系列1-通过应用场景看Nginx的反向代理 Ngnix技术研究系列2-基于Redis实现动态路由 发现,应该加一篇OpenResty的安装部署说明,方便大家按图索骥 ...

  5. 使用SpringAOP获取一次请求流经方法的调用次数和调用耗时

    引语 作为工程师,不能仅仅满足于实现了现有的功能逻辑,还必须深入认识系统.一次请求,流经了哪些方法,执行了多少次DB操作,访问了多少次文件操作,调用多少次API操作,总共有多少次IO操作,多少CPU操 ...

  6. mysql每天弹出窗口检测更新关闭方式...

    右击计算机-->管理-->系统工具-->任务计划程序-->MySQL<如下图>,选中右键删除或者禁用即可... 更新分界线--------------------- ...

  7. C# 复制值类型的变量和类

    C#大多数基元类型包括int.float.double.和char等,注意这里不包括string,这些都是值类型.将变量声明为值类型,编译器会生成代码来分配足以容纳这个值得内存块.编译器分配内存的时候 ...

  8. 转:【专题十二】实现一个简单的FTP服务器

    引言: 休息一个国庆节后好久没有更新文章了,主要是刚开始休息完心态还没有调整过来的, 现在差不多进入状态了, 所以继续和大家分享下网络编程的知识,在本专题中将和大家分享如何自己实现一个简单的FTP服务 ...

  9. 那些年 Qzone

    那些年转在Qzone里的: 不喊痛,不一定没感觉.不要求,不一定没期待.不落泪,不一定没伤痕.不说话,不一定没心声.沉默,不代表自己没话说.离开,不代表自己很潇洒.快乐,不代表自己没伤心.幸福,不代表 ...

  10. .NET 常用ORM之Nbear

    NBear是一个基于.Net 2.0.C#2.0开放全部源代码的的软件开发框架类库.NBear的设计目标是尽最大努力减少开发人员的工作量,最大程度提升开发效率,同时兼顾性能及可伸缩性. 一.新建项目并 ...