2010-1088
从 Trac 迁移的文章
这是从旧校内 Wiki 迁移的文章,可能存在一些样式问题,您可以向 memset0 反馈。
原文章内容如下:
Contest 5 by Bomb - A
Special Special Judge
题目给出了一个有n个元素的序列向量{An}作为标准,然后Fire 对每个元素在[a,b]范围内乱猜,问他瞎猜完之后每个元素之间的差的绝对值之和小于等于m的概率的精确值是多少,用分数表示。
如果不考虑数据范围,用f[i][j]表示猜到第i个元素,这i个元素分别与精确值的差的绝对值之和为j时,一共存在的情况数。那么有递退式:f[i][j]=sum{f[i][j-(s-Ai)]}(max(a,A[i]-j)<=s<=min(b,A[i]+j)).那么最后的结果就是sum{f[n][i]/(b-a+1)}(0<=i<=m),通分即可
但是现在要考虑高精度运算,可以采用JAVA中的BigInteger类帮助运算,免去了自己去写高精度。
JAVA程序:
{{{
#!java
import java.util.*;
import java.math.*;
public class Main
{
static int data[]=new int[100];
static BigInteger f[][]=new BigInteger [100][100];
static int abs(int s)
{
if (s<0)
return -s;
return s;
}
static BigInteger gcd(BigInteger a,BigInteger b)
{
if (a.equals(BigInteger.valueOf(0)))
return b;
return gcd(b.mod(a),a);
}
public static void main(String args[])
{
int n,m,a,b;
Scanner sin=new Scanner(System.in);
while (sin.hasNextInt())
{
n=sin.nextInt();
m=sin.nextInt();
a=sin.nextInt();
b=sin.nextInt();
for (int i=1;i<=n;i++)
{
data[i]=sin.nextInt();
}
for (int i=0;i<=n;i++)
for (int j=0;j<=m;j++)
f[i][j]=BigInteger.valueOf(0);
f[0][0]=BigInteger.valueOf(1);
for (int i=1;i<=n;i++)
for (int j=0;j<=m;j++)
{
int min=data[i]-j;
int max=data[i]+j;
if (min<a)
min=a;
if (max>b)
max=b;
for (int s=min;s<=max;s++)
{
int diff=abs(s-data[i]);
f[i][j]=f[i][j].add(f[i-1][j-diff]);
}
}
BigInteger sum=BigInteger.valueOf(0);
for (int i=0;i<=m;i++)
sum=sum.add(f[n][i]);
BigInteger d=BigInteger.valueOf(1);
for (int i=1;i<=n;i++)
d=d.multiply(BigInteger.valueOf(b-a+1));
BigInteger p=gcd(sum,d);
BigInteger aa=sum.divide(p);
BigInteger bb=d.divide(p);
System.out.println(aa+"/"+bb);
}
}
}
}}}
Contest 5 by Bomb - A
Special Special Judge
题目给出了一个有n个元素的序列向量{An}作为标准,然后Fire 对每个元素在[a,b]范围内乱猜,问他瞎猜完之后每个元素之间的差的绝对值之和小于等于m的概率的精确值是多少,用分数表示。
如果不考虑数据范围,用f[i][j]表示猜到第i个元素,这i个元素分别与精确值的差的绝对值之和为j时,一共存在的情况数。那么有递退式:f[i][j]=sum{f[i][j-(s-Ai)]}(max(a,A[i]-j)<=s<=min(b,A[i]+j)).那么最后的结果就是sum{f[n][i]/(b-a+1)}(0<=i<=m),通分即可
但是现在要考虑高精度运算,可以采用JAVA中的BigInteger类帮助运算,免去了自己去写高精度。
JAVA程序:
import java.util.*;
import java.math.*;
public class Main
{
static int data[]=new int[100];
static BigInteger f[][]=new BigInteger [100][100];
static int abs(int s)
{
if (s<0)
return -s;
return s;
}
static BigInteger gcd(BigInteger a,BigInteger b)
{
if (a.equals(BigInteger.valueOf(0)))
return b;
return gcd(b.mod(a),a);
}
public static void main(String args[])
{
int n,m,a,b;
Scanner sin=new Scanner(System.in);
while (sin.hasNextInt())
{
n=sin.nextInt();
m=sin.nextInt();
a=sin.nextInt();
b=sin.nextInt();
for (int i=1;i<=n;i++)
{
data[i]=sin.nextInt();
}
for (int i=0;i<=n;i++)
for (int j=0;j<=m;j++)
f[i][j]=BigInteger.valueOf(0);
f[0][0]=BigInteger.valueOf(1);
for (int i=1;i<=n;i++)
for (int j=0;j<=m;j++)
{
int min=data[i]-j;
int max=data[i]+j;
if (min<a)
min=a;
if (max>b)
max=b;
for (int s=min;s<=max;s++)
{
int diff=abs(s-data[i]);
f[i][j]=f[i][j].add(f[i-1][j-diff]);
}
}
BigInteger sum=BigInteger.valueOf(0);
for (int i=0;i<=m;i++)
sum=sum.add(f[n][i]);
BigInteger d=BigInteger.valueOf(1);
for (int i=1;i<=n;i++)
d=d.multiply(BigInteger.valueOf(b-a+1));
BigInteger p=gcd(sum,d);
BigInteger aa=sum.divide(p);
BigInteger bb=d.divide(p);
System.out.println(aa+"/"+bb);
}
}
}