zoukankan      html  css  js  c++  java
  • 题解 UVA10328 【Coin Toss】

    这道题目其实就是说有N张纸牌,问至少连续K张正面朝上的可能性是多少。


    可以用递推做。
    首先我们将题目所求从


    至少K张


    转化为


    总数 - 至多K张


    (为什么要这样自己想)

    设F[i][j]为前i个纸牌至多K张的种数。其中j记录第i张纸牌的状态,1为正面朝上,0为反面。

    那么可以总结出

     1 f[i][0] = f[i - 1][0] + f[i - 1][1];  

    1 f[i][1] = f[i - 1][0] + f[i - 1][1];
    2 if(i == k) f[i][1] -= 1;
    3 else if(i > k) f[i][1] -= f[i - k][0];

    最后要记住这道题需要写高精,我第一次就是这么扑街的。

    注:高精用的模板,手残就全加上了,事实上只用加减法。

    AC代码如下(洛谷上不知道为什么被积极拒绝,只好去Vjudge上提交。。。没去UVa才不是因为我没有注册。)

      1 #include <iostream> 
      2 #include <cstdio>
      3 #include <algorithm>
      4 #include <cstring>
      5 #include <cmath> 
      6 #include <vector>
      7 #include <cassert>
      8 using namespace std;
      9 
     10 const int maxn = 105;
     11 
     12 struct BigInteger {
     13     typedef unsigned long long LL;
     14 
     15     static const int BASE = 100000000;
     16     static const int WIDTH = 8;
     17     vector<int> s;
     18 
     19     BigInteger& clean(){while(!s.back()&&s.size()>1)s.pop_back(); return *this;}
     20     BigInteger(LL num = 0) {*this = num;}
     21     BigInteger(string s) {*this = s;}
     22     BigInteger& operator = (long long num) {
     23         s.clear();
     24         do {
     25             s.push_back(num % BASE);
     26             num /= BASE;
     27         } while (num > 0);
     28         return *this;
     29     }
     30     BigInteger& operator = (const string& str) {
     31         s.clear();
     32         int x, len = (str.length() - 1) / WIDTH + 1;
     33         for (int i = 0; i < len; i++) {
     34             int end = str.length() - i*WIDTH;
     35             int start = max(0, end - WIDTH);
     36             sscanf(str.substr(start,end-start).c_str(), "%d", &x);
     37             s.push_back(x);
     38         }
     39         return (*this).clean();
     40     }
     41 
     42     BigInteger operator + (const BigInteger& b) const {
     43         BigInteger c; c.s.clear();
     44         for (int i = 0, g = 0; ; i++) {
     45             if (g == 0 && i >= s.size() && i >= b.s.size()) break;
     46             int x = g;
     47             if (i < s.size()) x += s[i];
     48             if (i < b.s.size()) x += b.s[i];
     49             c.s.push_back(x % BASE);
     50             g = x / BASE;
     51         }
     52         return c;
     53     }
     54     BigInteger operator - (const BigInteger& b) const {
     55         assert(b <= *this); // 减数不能大于被减数
     56         BigInteger c; c.s.clear();
     57         for (int i = 0, g = 0; ; i++) {
     58             if (g == 0 && i >= s.size() && i >= b.s.size()) break;
     59             int x = s[i] + g;
     60             if (i < b.s.size()) x -= b.s[i];
     61             if (x < 0) {g = -1; x += BASE;} else g = 0;
     62             c.s.push_back(x);
     63         }
     64         return c.clean();
     65     }
     66     BigInteger operator * (const BigInteger& b) const {
     67         int i, j; LL g;
     68         vector<LL> v(s.size()+b.s.size(), 0);
     69         BigInteger c; c.s.clear();
     70         for(i=0;i<s.size();i++) for(j=0;j<b.s.size();j++) v[i+j]+=LL(s[i])*b.s[j];
     71         for (i = 0, g = 0; ; i++) {
     72             if (g ==0 && i >= v.size()) break;
     73             LL x = v[i] + g;
     74             c.s.push_back(x % BASE);
     75             g = x / BASE;
     76         }
     77         return c.clean();
     78     }
     79     BigInteger operator / (const BigInteger& b) const {
     80         assert(b > 0);  // 除数必须大于0
     81         BigInteger c = *this;       // 商:主要是让c.s和(*this).s的vector一样大
     82         BigInteger m;               // 余数:初始化为0
     83         for (int i = s.size()-1; i >= 0; i--) {
     84             m = m*BASE + s[i];
     85             c.s[i] = bsearch(b, m);
     86             m -= b*c.s[i];
     87         }
     88         return c.clean();
     89     }
     90     BigInteger operator % (const BigInteger& b) const { //方法与除法相同
     91         BigInteger c = *this;
     92         BigInteger m;
     93         for (int i = s.size()-1; i >= 0; i--) {
     94             m = m*BASE + s[i];
     95             c.s[i] = bsearch(b, m);
     96             m -= b*c.s[i];
     97         }
     98         return m;
     99     }
    100     // 二分法找出满足bx<=m的最大的x
    101     int bsearch(const BigInteger& b, const BigInteger& m) const{
    102         int L = 0, R = BASE-1, x;
    103         while (1) {
    104             x = (L+R)>>1;
    105             if (b*x<=m) {if (b*(x+1)>m) return x; else L = x;}
    106             else R = x;
    107         }
    108     }
    109     BigInteger& operator += (const BigInteger& b) {*this = *this + b; return *this;}
    110     BigInteger& operator -= (const BigInteger& b) {*this = *this - b; return *this;}
    111     BigInteger& operator *= (const BigInteger& b) {*this = *this * b; return *this;}
    112     BigInteger& operator /= (const BigInteger& b) {*this = *this / b; return *this;}
    113     BigInteger& operator %= (const BigInteger& b) {*this = *this % b; return *this;}
    114 
    115     bool operator < (const BigInteger& b) const {
    116         if (s.size() != b.s.size()) return s.size() < b.s.size();
    117         for (int i = s.size()-1; i >= 0; i--)
    118             if (s[i] != b.s[i]) return s[i] < b.s[i];
    119         return false;
    120     }
    121     bool operator >(const BigInteger& b) const{return b < *this;}
    122     bool operator<=(const BigInteger& b) const{return !(b < *this);}
    123     bool operator>=(const BigInteger& b) const{return !(*this < b);}
    124     bool operator!=(const BigInteger& b) const{return b < *this || *this < b;}
    125     bool operator==(const BigInteger& b) const{return !(b < *this) && !(b > *this);}
    126 };
    127 
    128 ostream& operator << (ostream& out, const BigInteger& x) {
    129     out << x.s.back();
    130     for (int i = x.s.size()-2; i >= 0; i--) {
    131         char buf[20];
    132         sprintf(buf, "%08d", x.s[i]);
    133         for (int j = 0; j < strlen(buf); j++) out << buf[j];
    134     }
    135     return out;
    136 }
    137 
    138 istream& operator >> (istream& in, BigInteger& x) {
    139     string s;
    140     if (!(in >> s)) return in;
    141     x = s;
    142     return in;
    143 }
    144 
    145 int n, k;
    146 BigInteger f[maxn][2];
    147 
    148 int main() {
    149     while(cin >> n >> k) {
    150         memset(f, 0, sizeof(f));
    151         f[0][1] = 1;
    152         for(int i = 1; i <= n; i++) {
    153             f[i][0] = f[i - 1][0] + f[i - 1][1]; 
    154             f[i][1] = f[i - 1][0] + f[i - 1][1];
    155             if(i == k) f[i][1] = f[i][1] - 1;
    156             else if(i > k) f[i][1] = f[i][1] - f[i - k][0];
    157         }
    158         BigInteger a = 1, t = 2;
    159         for(int i = 0; i < n; i++) a = t * a;
    160         cout << a - f[n][1] - f[n][0] << endl;
    161     }
    162 }
  • 相关阅读:
    python学习之列表和字典
    python学习之字符串(下)
    python学习之数字
    python学习之核心数据类型
    android 学习Layout布局的使用
    android学习SeekBar的使用
    android学习Gallery和ImageSwitch的使用
    android学习ScrollView的使用
    android学习ViewFlipper的使用
    C#怎么判断传入int值是否是枚举里面的值
  • 原文地址:https://www.cnblogs.com/ilverene/p/UVA10328.html
Copyright © 2011-2022 走看看