题解 UVA10328 【Coin Toss】
这道题目其实就是说有N张纸牌,问至少连续K张正面朝上的可能性是多少。
可以用递推做。
首先我们将题目所求从
至少K张
转化为
总数 - 至多K张
(为什么要这样自己想)
设F[i][j]为前i个纸牌至多K张的种数。其中j记录第i张纸牌的状态,1为正面朝上,0为反面。
那么可以总结出
f[i][] = f[i - ][] + f[i - ][];
f[i][] = f[i - ][] + f[i - ][];
if(i == k) f[i][] -= ;
else if(i > k) f[i][] -= f[i - k][];
最后要记住这道题需要写高精,我第一次就是这么扑街的。
注:高精用的模板,手残就全加上了,事实上只用加减法。
AC代码如下(洛谷上不知道为什么被积极拒绝,只好去Vjudge上提交。。。没去UVa才不是因为我没有注册。)
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <vector>
#include <cassert>
using namespace std; const int maxn = ; struct BigInteger {
typedef unsigned long long LL; static const int BASE = ;
static const int WIDTH = ;
vector<int> s; BigInteger& clean(){while(!s.back()&&s.size()>)s.pop_back(); return *this;}
BigInteger(LL num = ) {*this = num;}
BigInteger(string s) {*this = s;}
BigInteger& operator = (long long num) {
s.clear();
do {
s.push_back(num % BASE);
num /= BASE;
} while (num > );
return *this;
}
BigInteger& operator = (const string& str) {
s.clear();
int x, len = (str.length() - ) / WIDTH + ;
for (int i = ; i < len; i++) {
int end = str.length() - i*WIDTH;
int start = max(, end - WIDTH);
sscanf(str.substr(start,end-start).c_str(), "%d", &x);
s.push_back(x);
}
return (*this).clean();
} BigInteger operator + (const BigInteger& b) const {
BigInteger c; c.s.clear();
for (int i = , g = ; ; i++) {
if (g == && i >= s.size() && i >= b.s.size()) break;
int x = g;
if (i < s.size()) x += s[i];
if (i < b.s.size()) x += b.s[i];
c.s.push_back(x % BASE);
g = x / BASE;
}
return c;
}
BigInteger operator - (const BigInteger& b) const {
assert(b <= *this); // 减数不能大于被减数
BigInteger c; c.s.clear();
for (int i = , g = ; ; i++) {
if (g == && i >= s.size() && i >= b.s.size()) break;
int x = s[i] + g;
if (i < b.s.size()) x -= b.s[i];
if (x < ) {g = -; x += BASE;} else g = ;
c.s.push_back(x);
}
return c.clean();
}
BigInteger operator * (const BigInteger& b) const {
int i, j; LL g;
vector<LL> v(s.size()+b.s.size(), );
BigInteger c; c.s.clear();
for(i=;i<s.size();i++) for(j=;j<b.s.size();j++) v[i+j]+=LL(s[i])*b.s[j];
for (i = , g = ; ; i++) {
if (g == && i >= v.size()) break;
LL x = v[i] + g;
c.s.push_back(x % BASE);
g = x / BASE;
}
return c.clean();
}
BigInteger operator / (const BigInteger& b) const {
assert(b > ); // 除数必须大于0
BigInteger c = *this; // 商:主要是让c.s和(*this).s的vector一样大
BigInteger m; // 余数:初始化为0
for (int i = s.size()-; i >= ; i--) {
m = m*BASE + s[i];
c.s[i] = bsearch(b, m);
m -= b*c.s[i];
}
return c.clean();
}
BigInteger operator % (const BigInteger& b) const { //方法与除法相同
BigInteger c = *this;
BigInteger m;
for (int i = s.size()-; i >= ; i--) {
m = m*BASE + s[i];
c.s[i] = bsearch(b, m);
m -= b*c.s[i];
}
return m;
}
// 二分法找出满足bx<=m的最大的x
int bsearch(const BigInteger& b, const BigInteger& m) const{
int L = , R = BASE-, x;
while () {
x = (L+R)>>;
if (b*x<=m) {if (b*(x+)>m) return x; else L = x;}
else R = x;
}
}
BigInteger& operator += (const BigInteger& b) {*this = *this + b; return *this;}
BigInteger& operator -= (const BigInteger& b) {*this = *this - b; return *this;}
BigInteger& operator *= (const BigInteger& b) {*this = *this * b; return *this;}
BigInteger& operator /= (const BigInteger& b) {*this = *this / b; return *this;}
BigInteger& operator %= (const BigInteger& b) {*this = *this % b; return *this;} bool operator < (const BigInteger& b) const {
if (s.size() != b.s.size()) return s.size() < b.s.size();
for (int i = s.size()-; i >= ; i--)
if (s[i] != b.s[i]) return s[i] < b.s[i];
return false;
}
bool operator >(const BigInteger& b) const{return b < *this;}
bool operator<=(const BigInteger& b) const{return !(b < *this);}
bool operator>=(const BigInteger& b) const{return !(*this < b);}
bool operator!=(const BigInteger& b) const{return b < *this || *this < b;}
bool operator==(const BigInteger& b) const{return !(b < *this) && !(b > *this);}
}; ostream& operator << (ostream& out, const BigInteger& x) {
out << x.s.back();
for (int i = x.s.size()-; i >= ; i--) {
char buf[];
sprintf(buf, "%08d", x.s[i]);
for (int j = ; j < strlen(buf); j++) out << buf[j];
}
return out;
} istream& operator >> (istream& in, BigInteger& x) {
string s;
if (!(in >> s)) return in;
x = s;
return in;
} int n, k;
BigInteger f[maxn][]; int main() {
while(cin >> n >> k) {
memset(f, , sizeof(f));
f[][] = ;
for(int i = ; i <= n; i++) {
f[i][] = f[i - ][] + f[i - ][];
f[i][] = f[i - ][] + f[i - ][];
if(i == k) f[i][] = f[i][] - ;
else if(i > k) f[i][] = f[i][] - f[i - k][];
}
BigInteger a = , t = ;
for(int i = ; i < n; i++) a = t * a;
cout << a - f[n][] - f[n][] << endl;
}
}
题解 UVA10328 【Coin Toss】的更多相关文章
- UVA 10328 - Coin Toss dp+大数
题目链接: https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_proble ...
- UVA 10328 Coin Toss
Coin Toss Time Limit: 3000ms Memory Limit: 131072KB This problem will be judged on UVA. Original ID: ...
- Coin Toss(uva 10328,动态规划递推,限制条件,至少转至多,高精度)
有n张牌,求出至少有k张牌连续是正面的排列的种数.(1=<k<=n<=100) Toss is an important part of any event. When everyt ...
- UVa 10328 Coin Toss(Java大数+递推)
https://vjudge.net/problem/UVA-10328 题意: 有H和T两个字符,现在要排成n位的字符串,求至少有k个字符连续的方案数. 思路:这道题目和ZOJ3747是差不多的,具 ...
- POJ 3440 Coin Toss(概率)
题目链接 概率问题,像是概率论上学的均匀分布,是不是呢,忘了... 概率同面积有关系,我写的各种搓,然后此题格式十分变态,=前有的时候俩空格,有的时候一个空格.代码各种搓. #include < ...
- UVa 10328 - Coin Toss (递推)
题意:给你一个硬币,抛掷n次,问出现连续至少k个正面向上的情况有多少种. 原题中问出现连续至少k个H的情况,很难下手.我们可以试着将问题转化一下. 设dp[i][j]表示抛掷i个硬币出现连续至多j个H ...
- POJ 3440 Coin Toss(求概率)
题目链接 题意 :把硬币往棋盘上扔,分别求出硬币占1,2,3,4个格子的时候的概率. 思路 : 求出公式输出,不过要注意输出格式,我还因为输入的时候用了int类型错了好几次..... #include ...
- poj 3440 Coin Toss 概率问题
这题主要是推导数学公式!!! 将概率问题转化为圆心所在的面积! 代码如下: #include<iostream> #include<stdio.h> #include<a ...
- Coin Toss
http://acm.hust.edu.cn/vjudge/contest/view.action?cid=31329#problem/G 使用二维数组f[ i ] [ j ] 表示前i 位中有j个 ...
随机推荐
- Glide中的回调:targets
Glide隐藏了一大推复杂的在后台的场景,Glide做了所有的网络请求和处理在后台线程中,准备好了切回到ui线程后更新ImageView. 假设ImageView不再是图像的最后一步.我们只要Bitm ...
- dialog.setCancelable与setCanceledOnTouchOutside的区别
dialog.setCancelable(false); dialog弹出后会点击屏幕或物理返回键,dialog不消失 dialog.setCanceledOnTouchOutside(false); ...
- e.Row.Attributes.Add
其实看到属性这个单词,还有点发憷呢,C#里面有个关键词是Attributes, 搞了半天貌似没有弄清楚 e.Row.Attributes.Add()函数的介绍,包括参数,什么是Attributes 就 ...
- pic减法进位问题
1.pic指令中subwf是 F - Wreg,且如果F>=Wreg,则C=1:如果F<Wreg,则C=0:这是由于pic的减法是加上减数的补码实现的.例如3-2,其实是3+FE=01,进 ...
- Windows server 2012R清除并重建SID 用于制作封装模板
首先介绍下什么是SID SID也就是安全标识符(Security Identifiers),是标识用户.组和计算机帐户的唯一的号码.在第一次创建该帐户时,将给网络上的每一个帐户发布一个唯一的 SID. ...
- 第三方-FastDFS分布式文件系统
1.什么是FastDFS? FastDFS 是用 c 语言编写的一款开源的分布式文件系统.FastDFS 为互联网量身定制, 充分考虑了冗余备份.负载均衡.线性扩容等机制,并注重高可用.高性能等指标, ...
- [ZJOI2015]幻想乡战略游戏(点分树)
题意自己看... 思路 没想到今(昨)天刷着刷着点分治的水题,就刷出来了一个点分树... 然后就疯狂地找题解,代码,最后终于把它给弄懂了. 点分树——动态点分治,对于此题来说,我们设u为当前的补给站位 ...
- 题解 洛谷 P4047 【[JSOI2010]部落划分】
我觉得几乎就是一道最小生成树模板啊... 题解里许多大佬都说选第n-k+1条边,可我觉得要这么讲比较容易理解 (虚边为能选的边,实边为最小生成树) 令n=5,k=2,(1,3)<(1,2)< ...
- 2015 Multi-University Training Contest 2 hdu 5308 I Wanna Become A 24-Point Master
I Wanna Become A 24-Point Master Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 ...
- [数位dp] bzoj 3209 花神的数论题
题意:中文题. 思路:和普通数位dp一样,这里转换成二进制,然后记录有几个一. 统计的时候乘起来就好了. 代码: #include"cstdlib" #include"c ...