10328 - Coin Toss (dp 高精度)

来源:互联网 发布:淘宝ted baker 编辑:程序博客网 时间:2024/05/22 18:55



 Coin Toss 

Toss is an important part of any event. When everything becomes equal toss is the ultimate decider. Normally a fair coin is used for Toss. A coin has two sides head(H) and tail(T). Superstition may work in case of choosing head or tail. If anyone becomes winner choosing head he always wants to choose head. Nobody believes that his winning chance is 50-50. However in this problem we will deal with a fair coin and n times tossing of such a coin. The result of such a tossing can be represented by a string. Such as if 3 times tossing is used then there are possible 8 outcomes.


HHH HHT HTH HTT THH THT TTH TTT

As the coin is fair we can consider that the probability of each outcome is also equal. For simplicity we can consider that if the same thing is repeated 8 times we can expect to get each possible sequence once.

The Problem

In the above example we see 1 sequnce has 3 consecutive H, 3 sequence has 2 consecutive H and 7 sequence has at least single H. You have to generalize it. Suppose a coin is tossed n times. And the same process is repeated 2^n times. How many sequence you will get which contains a consequnce of H of length at least k.

The Input

The input will start with two positive integer, n and k (1<=k<=n<=100). Input is terminated by EOF.

The Output

For each test case show the result in a line as specified in the problem statement.

Sample Input

4 14 24 34 46 2

Sample Output

1583143

题意:给定n,k。表示投n次硬币,连续是正面的次数不少于k的总数。

思路:dp[i][j]表示前i次,连续正面不超过j的总情况数,要用高精度

代码:

#include <stdio.h>#include <string.h>#include <math.h>#define max(a,b) (a)>(b)?(a):(b)#define min(a,b) (a)<(b)?(a):(b)const int MAXSIZE = 1005;struct bign {int s[MAXSIZE];bign (){memset(s, 0, sizeof(s));}bign (int number) {*this = number;}bign (const char* number) {*this = number;}    void put();bign mul(int d);void del();    bign operator =  (char *num);bign operator =  (int num);bool operator <  (const bign& b) const;bool operator >  (const bign& b) const { return b < *this; }bool operator <= (const bign& b) const { return !(b < *this); }bool operator >= (const bign& b) const { return !(*this < b); }bool operator != (const bign& b) const { return b < *this || *this < b;}bool operator == (const bign& b) const { return !(b != *this); }    bign operator + (const bign& c);bign operator * (const bign& c);bign operator - (const bign& c);int  operator / (const bign& c);bign operator / (int k);bign operator % (const bign &c);int  operator % (int k);void operator ++ ();bool operator -- ();};bign bign::operator = (char *num) {s[0] = strlen(num);for (int i = 1; i <= s[0]; i++)s[i] = num[s[0] - i] - '0';return *this;}bign bign::operator = (int num) {char str[MAXSIZE];sprintf(str, "%d", num);return *this = str;}bool bign::operator < (const bign& b) const {if (s[0] != b.s[0])return s[0] < b.s[0];for (int i = s[0]; i; i--)if (s[i] != b.s[i])return s[i] < b.s[i];return false;}bign bign::operator + (const bign& c) {int sum = 0;bign ans;ans.s[0] = max(s[0], c.s[0]);for (int i = 1; i <= ans.s[0]; i++) {if (i <= s[0]) sum += s[i];if (i <= c.s[0]) sum += c.s[i];ans.s[i] = sum % 10;sum /= 10;}while (sum) {ans.s[++ans.s[0]] = sum % 10;sum /= 10;}return ans;}bign bign::operator * (const bign& c) {bign ans;ans.s[0] = 0; for (int i = 1; i <= c.s[0]; i++){  int g = 0;  for (int j = 1; j <= s[0]; j++){  int x = s[j] * c.s[i] + g + ans.s[i + j - 1];  ans.s[i + j - 1] = x % 10;  g = x / 10;  }  int t = i + s[0] - 1;while (g){  ++t;g += ans.s[t];ans.s[t] = g % 10;g = g / 10;  }  ans.s[0] = max(ans.s[0], t);}  ans.del();return ans;}bign bign::operator - (const bign& c) {bign ans = *this; int i;for (i = 1; i <= c.s[0]; i++) {if (ans.s[i] < c.s[i]) {ans.s[i] += 10;ans.s[i + 1]--;;}ans.s[i] -= c.s[i];}for (i = 1; i <= ans.s[0]; i++) {if (ans.s[i] < 0) {ans.s[i] += 10;ans.s[i + 1]--;}}ans.del();return ans;}int bign::operator / (const bign& c) {int ans = 0;bign d = *this;while (d >= c) {d = d - c;ans++;}return ans;}bign bign::operator / (int k) {bign ans; ans.s[0] = s[0];int num = 0;  for (int i = s[0]; i; i--) {  num = num * 10 + s[i];  ans.s[i] = num / k;  num = num % k;  }  ans.del();return ans;}int bign:: operator % (int k){  int sum = 0;  for (int i = s[0]; i; i--){  sum = sum * 10 + s[i];  sum = sum % k;  }  return sum;  } bign bign::operator % (const bign &c) {bign now = *this;while (now >= c) {now = now - c;now.del();}return now;}void bign::operator ++ () {s[1]++;for (int i = 1; s[i] == 10; i++) {s[i] = 0;s[i + 1]++;s[0] = max(s[0], i + 1);}}bool bign::operator -- () {del();if (s[0] == 1 && s[1] == 0) return false;int i;for (i = 1; s[i] == 0; i++)s[i] = 9;s[i]--;del();return true;}void bign::put() {if (s[0] == 0)printf("0");elsefor (int i = s[0]; i; i--)printf("%d", s[i]);}bign bign::mul(int d) {s[0] += d; int i;for (i = s[0]; i > d; i--)s[i] = s[i - d];for (i = d; i; i--)s[i] = 0;return *this;}void bign::del() {while (s[s[0]] == 0) {s[0]--;if (s[0] == 0) break;}}const int MAXN = 105;int n, k;bign dp[MAXN][MAXN], two = 2;void init() {bign mi[MAXN];mi[0] = 1;for (int k = 0; k <= 100; k ++) {dp[k][0] = dp[0][k] = 1;}for (int i = 1; i <= 100; i ++) {mi[i] = mi[i - 1] * two;for (int j = 0; j <= 100; j ++) {if (j == i - 1)dp[i][j] = dp[i - 1][j] * two - dp[0][j];else if (j < i - 1) {dp[i][j] = dp[i - 1][j] * two - dp[i - 2 - j][j];}else {dp[i][j] = mi[i];}}}}bign solve() {return dp[n][n] - dp[n][k - 1];}int main() {init();while (~scanf("%d%d", &n, &k)) {solve().put();printf("\n");}return 0;}
原创粉丝点击