BZOJ NOI 1999 钉子和小球 动态规划+分数类

题目大意:不太好描写叙述,自己看吧。。

思路:首先从最上面的点開始考虑。由于球一定是从最上面開始往下掉,所以球经过最上面的点的概率是1,然后他会有1/2的几率向左,1/2的几率向右,也就是以下的两个点均分上面点的几率。

当然这是全部的点都存在的情况。假设有哪里的点不存在了,那么求落到这个点的几率不变,然后它的全部几率都会加在在它以下两行且在正下方的点。

依照这样写dp方程。显然是不难的。之后就是恶心的输出了。两个方案,1.遇到小数就*2,保证它是整数。可是最高有50层。就要考虑一下2^50这么大,加上一些复杂的情况,非常可能爆掉__int64,舍弃这样的方法。2.就是写一个分数类。

。这玩应还是第一次写,挺有趣的。。

CODE:

#include <cstdio>
#include <iomanip>
#include <cstring>
#include <iostream>
#include <algorithm>
#define MAX 100
using namespace std;

long long Gcd(long long x,long long y) {return y ? Gcd(y,x % y):x;}

struct Fraction{
	long long up;
	long long down;

	Fraction(long long _ = 0,long long __ = 1):up(_),down(__) {}
	void Reduction() {
		long long gcd = Gcd(up,down);
		up /= gcd;
		down /= gcd;
	}
	Fraction operator +(const Fraction &a)const {
		Fraction re;
		long long gcd = Gcd(down,a.down);
		re.down = a.down / gcd * down;
		re.up = (up * a.down + a.up * down) / gcd;
		re.Reduction();
		return re;
	}
	Fraction operator +=(const Fraction &a) {
		*this = *this + a;
		return *this;
	}
	Fraction operator *(const Fraction &a)const {
		Fraction re(up * a.up,down * a.down);
		re.Reduction();
		return re;
	}
};

int cnt,ask;
char map[MAX][MAX];
Fraction f[MAX][MAX];

inline char Judge();

int main()
{
	cin >> cnt >> ask;
	for(int i = 1;i <= cnt; ++i)
		for(int j = 1;j <= i; ++j)
			map[i][j] = Judge();
	f[1][1] = Fraction(1,1);
	for(int i = 1;i <= cnt; ++i)
		for(int j = 1;j <= cnt; ++j) {
			if(map[i][j] == '*') {
				f[i + 1][j] += f[i][j] * Fraction(1,2);
				f[i + 1][j + 1] += f[i][j] * Fraction(1,2);
			}
			else	f[i + 2][j + 1] += f[i][j];
		}
	printf("%lld/%lld",f[cnt + 1][ask + 1].up,f[cnt + 1][ask + 1].down);
	return 0;
}

inline char Judge()
{
	char c;
	while(c = getchar()) {
		if(c == '*')	return '*';
		else if(c == '.')	return '.';
	}
}

时间: 2024-10-18 18:25:12

BZOJ NOI 1999 钉子和小球 动态规划+分数类的相关文章

BZOJ 1867 NOI1999 钉子和小球 动态规划

题目大意:给定一个钉子阵,小球从最上方的钉子释放,求到达最底端某个位置的概率 只需要DP就好了 f[i][j]表示小球落在第i行第j个钉子上的概率 如果一个点有钉子 f[i+1][j]和f[i+1][j+1]平分这个点的概率 如果一个点没有钉子 f[i+2][j+1]得到这个点的全部概率 最后输出f[n+1][m+1]即可 注意不能输出回车 否则PE 无视这凶残的结构体操作符重载吧0.0 #include<cstdio> #include<cstring> #include<

[bzoj1867][Noi1999][钉子和小球] (动态规划)

Description Input 第1行为整数n(2<=n<=50)和m(0<=m<=n).以下n行依次为木板上从上至下n行钉子的信息,每行中‘*’表示钉子还在,‘.’表示钉子被拔去,注意在这n行中空格符可能出现在任何位置. Output 仅一行,是一个既约分数(0写成0/1),为小球落在编号为m的格子中的概pm.既约分数的定义:A/B是既约分数,当且仅当A.B为正整数且A和B没有大于1的公因子. Sample Input 5 2 Sample Output 7/16 Solut

NOI 191钉子和小球.cpp

1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 using namespace std; 5 long long f[101][101]; 6 int n,m; 7 char c; 8 long long gcd(long long ,long long ); 9 int main() 10 { 11 scanf("%d%d",&n,&m); 12 f[1][

bzoj千题计划189:bzoj1867: [Noi1999]钉子和小球

http://www.lydsy.com/JudgeOnline/problem.php?id=1867 dp[i][j] 落到(i,j)的方案数 dp[i][j]=0.5*dp[i-1][j]   [(i-1,j)位置有钉子] + 0.5*dp[i-1][j-1]    [(i-1.j-1)位置有钉子] + dp[i-1][j-2]    [(i-1,j-2)位置没有钉子] #include<cstdio> #include<iostream> using namespace s

codevs 1709 钉子和小球

1709 钉子和小球 1999年NOI全国竞赛 时间限制: 2 s 空间限制: 128000 KB 题目等级 : 大师 Master 题解 查看运行结果题目描述 Description有一个三角形木板,竖直立放,上面钉着n(n+1)/2颗钉子,还有(n+1)个格子(当n=5时如图1).每颗钉子和周围的钉子的距离都等于d,每个格子的宽度也都等于d,且除了最左端和最右端的格子外每个格子都正对着最下面一排钉子的间隙. 让一个直径略小于d的小球中心正对着最上面的钉子在板上自由滚落,小球每碰到一个钉子都可

实验11:Problem C: 分数类的乘法

Home Web Board ProblemSet Standing Status Statistics Problem C: 分数类的乘法 Problem C: 分数类的乘法 Time Limit: 3 Sec  Memory Limit: 128 MBSubmit: 650  Solved: 477[Submit][Status][Web Board] Description 封装一个分数类Fract,用来处理分数功能和运算,支持以下操作: 1. 构造:传入两个参数n和m,表示n/m:分数在

Problem F: 分数类的类型转换

Description 封装一个分数类Fract,用来处理分数功能和运算,支持以下操作: 1. 构造:传入两个参数n和m,表示n/m:分数在构造时立即转化成最简分数. 2. show()函数:分数输出为"a/b"或"-a/b"的形式,a.b都是无符号整数.若a为0或b为1,只输出符号和分子,不输出"/"和分母. 3. double类型转换函数:用分子除以分母,得到的小数.注意:分子为0时不要输出为"-0" ----------

Problem C: 分数类的乘法

Description 封装一个分数类Fract,用来处理分数功能和运算,支持以下操作: 1. 构造:传入两个参数n和m,表示n/m:分数在构造时立即转化成最简分数. 2. show()函数:分数输出为"a/b"或"-a/b"的形式,a.b都是无符号整数.若a为0或b为1,只输出符号和分子,不输出"/"和分母. 3. 在分数类上重载乘法运算符,进行分数的乘法运算 ------------------------------------------

实验11:Problem A: 分数类的输出

注意如果是负数,要把负号放在分子上 Home Web Board ProblemSet Standing Status Statistics Problem A: 分数类的输出 Problem A: 分数类的输出 Time Limit: 3 Sec  Memory Limit: 128 MBSubmit: 1453  Solved: 574[Submit][Status][Web Board] Description 封装一个分数类Fract,用来处理分数功能和运算,支持以下操作: 1. 构造: