POJ2084 Game of Connections(数学,dp)
题目链接。
分析:
简单的 Catalan 数
将x~y编号,设解为 d(x, y), d(x, y) = {d(x+1,i-1)*d(i+1,y)}, 其中 x+1<= i <= y, 注意x~y之间的数必须为偶数个。
这题除了要dp,还要使用大数(竟然有种想用java的冲动了)。大数呢,用了下现成的模板。
AC代码如下:
- #include<iostream>
- #include<string>
- #include<algorithm>
- #include <cstdio>
- #include <cstring>
- using namespace std;
- #define MAXN 9999
- #define DLEN 4
- class BigNum
- {
- private:
- int a[]; //可以控制大数的位数
- int len; //大数长度
- public:
- BigNum(){ len = ; memset(a,,sizeof(a)); } //构造函数
- BigNum(const int); //将一个int类型的变量转化为大数
- BigNum(const BigNum &); //拷贝构造函数
- BigNum &operator=(const BigNum &); //重载赋值运算符,大数之间进行赋值运算
- friend ostream& operator<<(ostream&, BigNum&); //重载输出运算符
- BigNum operator+(const BigNum &) const; //重载加法运算符,两个大数之间的相加运算
- BigNum operator*(const BigNum &) const; //重载乘法运算符,两个大数之间的相乘运算
- bool operator>(const int & t)const; //大数和一个int类型的变量的大小比较
- bool operator>(const BigNum & T)const; //大数和另一个大数的大小比较
- };
- BigNum dp[][];
- BigNum d(int x, int y) {
- if(x == y) return ;
- if(x > y) return ;
- if(dp[x][y] > ) return dp[x][y];
- if(y - x == ) return (dp[x][y] = );
- BigNum ans = ;
- for(int i = x+; i <= y; i +=) {
- ans = ans + d(x+, i-)*d(i+, y);
- }
- return (dp[x][y] = ans);
- }
- int main(){
- int n;
- while(scanf("%d", &n) == && n != -) {
- BigNum ans = d(, *n);
- cout << ans << endl;
- }
- return ;
- }
- BigNum::BigNum(const int b) //将一个int类型的变量转化为大数
- {
- int c,d = b;
- len = ;
- memset(a,,sizeof(a));
- while(d > MAXN)
- {
- c = d - (d / (MAXN + )) * (MAXN + );
- d = d / (MAXN + );
- a[len++] = c;
- }
- a[len++] = d;
- }
- BigNum::BigNum(const BigNum & T) : len(T.len) //拷贝构造函数
- {
- int i;
- memset(a,,sizeof(a));
- for(i = ; i < len ; i++)
- a[i] = T.a[i];
- }
- BigNum & BigNum::operator=(const BigNum & n) //重载赋值运算符,大数之间进行赋值运算
- {
- int i;
- len = n.len;
- memset(a,,sizeof(a));
- for(i = ; i < len ; i++)
- a[i] = n.a[i];
- return *this;
- }
- ostream& operator<<(ostream& out, BigNum& b) //重载输出运算符
- {
- int i;
- cout << b.a[b.len - ];
- for(i = b.len - ; i >= ; i--)
- {
- cout.width(DLEN);
- cout.fill('');
- cout << b.a[i];
- }
- return out;
- }
- BigNum BigNum::operator+(const BigNum & T) const //两个大数之间的相加运算
- {
- BigNum t(*this);
- int i,big; //位数
- big = T.len > len ? T.len : len;
- for(i = ; i < big ; i++)
- {
- t.a[i] +=T.a[i];
- if(t.a[i] > MAXN)
- {
- t.a[i + ]++;
- t.a[i] -=MAXN+;
- }
- }
- if(t.a[big] != )
- t.len = big + ;
- else
- t.len = big;
- return t;
- }
- BigNum BigNum::operator*(const BigNum & T) const //两个大数之间的相乘运算
- {
- BigNum ret;
- int i,j,up;
- int temp,temp1;
- for(i = ; i < len ; i++)
- {
- up = ;
- for(j = ; j < T.len ; j++)
- {
- temp = a[i] * T.a[j] + ret.a[i + j] + up;
- if(temp > MAXN)
- {
- temp1 = temp - temp / (MAXN + ) * (MAXN + );
- up = temp / (MAXN + );
- ret.a[i + j] = temp1;
- }
- else
- {
- up = ;
- ret.a[i + j] = temp;
- }
- }
- if(up != )
- ret.a[i + j] = up;
- }
- ret.len = i + j;
- while(ret.a[ret.len - ] == && ret.len > )
- ret.len--;
- return ret;
- }
- bool BigNum::operator >(const int & t) const //大数和一个int类型的变量的大小比较
- {
- BigNum b(t);
- return *this>b;
- }
- bool BigNum::operator>(const BigNum & T) const //大数和另一个大数的大小比较
- {
- int ln;
- if(len > T.len)
- return true;
- else if(len == T.len)
- {
- ln = len - ;
- while(a[ln] == T.a[ln] && ln >= )
- ln--;
- if(ln >= && a[ln] > T.a[ln])
- return true;
- else
- return false;
- }
- else
- return false;
- }
POJ2084 Game of Connections(数学,dp)的更多相关文章
- 数学+dp HDOJ 5317 RGCDQ
题目传送门 /* 题意:给一个区间,问任意两个数的素数因子的GCD最大 数学+dp:预处理出f[i],发现f[i] <= 7,那么用dp[i][j] 记录前i个f[]个数为j的数有几个, dp[ ...
- 数学+DP Codeforces Round #304 (Div. 2) D. Soldier and Number Game
题目传送门 /* 题意:这题就是求b+1到a的因子个数和. 数学+DP:a[i]保存i的最小因子,dp[i] = dp[i/a[i]] +1;再来一个前缀和 */ /***************** ...
- 拓扑排序+数学+DP【洛谷P1685】 游览
P1685 游览 题目描述 顺利通过了黄药师的考验,下面就可以尽情游览桃花岛了! 你要从桃花岛的西头开始一直玩到东头,然后在东头的码头离开.可是当你游玩了一次后,发现桃花岛的景色实在是非常的美丽!!! ...
- HDU 1041 Computer Transformation 数学DP题解
本题假设编程是使用DP思想直接打表就能够了. 假设是找规律就须要数学思维了. 规律就是看这些连续的0是从哪里来的. 我找到的规律是:1经过两次裂变之后就会产生一个00: 00经过两次裂变之后也会产生新 ...
- BZOJ 2302: [HAOI2011]Problem c(数学+DP)
题面: bzoj_2302 题解: 令\(dp[i][j]\)表示编号 \(\leq i\)的人有j个的方案数: \(cnt[i]\)表示编号指定为\(i\)的人数,\(sum[i]\)表示编号可以\ ...
- Codeforces 772C 构造 数学 + dp + exgcd
首先我们能注意到两个数x, y (0 < x , y < m) 乘以倍数互相可达当且仅当gcd(x, m) == gcd(y, m) 然后我们可以发现我们让gcd(x, m)从1开始出发走 ...
- CodeForces 402D Upgrading Array (数学+DP)
题意:给出一个数列,可以进行一种操作将某一个前缀除去他们的gcd,有一个函数f(x),f(1) = 0 , f(x) = f(x/p)+1,f(x) = f(x/p)-1(p是坏素数), 求 sum( ...
- 拓扑排序+数学+DP【p1685】游览
Description 顺利通过了黄药师的考验,下面就可以尽情游览桃花岛了! 你要从桃花岛的西头开始一直玩到东头,然后在东头的码头离开.可是当你游玩了一次后,发现桃花岛的景色实在是非常的美丽!!!于是 ...
- HDU - 1134 Game of Connections 【DP】
题目链接 http://acm.hdu.edu.cn/showproblem.php?pid=1134 题意 给出一个n 然后有2n个点 给两个点连一条边,最后连N条边,要求所有的边不能够交叉 问最多 ...
随机推荐
- POJ 3978 Primes(求范围素数个数)
POJ 3978 Primes(求范围素数个数) id=3978">http://poj.org/problem? id=3978 题意: 给你一个区间范围A和B,要你求出[A,B]内 ...
- Android为ListView的Item设置不同的布局
MainActivity如下: package cc.testlistview; import java.util.ArrayList; import java.util.HashMap; impor ...
- [转] Java多线程发展简史
这篇文章,大部分内容,是周五我做的一个关于如何进行Java多线程编程的Knowledge Sharing的一个整理,我希望能对Java从第一个版本开始,在多线程编程方面的大事件和发展脉络有一个描述,并 ...
- C++面试中string类的一种正确写法
C++ 的一个常见面试题是让你实现一个 String 类,限于时间,不可能要求具备 std::string 的功能,但至少要求能正确管理资源.具体来说: 能像 int 类型那样定义变量,并且支持赋值. ...
- Block小结
Blocks是C语言的扩充功能.用一句话来表示Blocks的扩充功能:带有自动变量(局部变量)的匿名函数. block其实是一个代码块,但是它的神奇之处在于在内联(inline)执行的时候(这和C++ ...
- 判断iPhone和iPad 判断设备版本
//判断iPhone和iPad #define IS_IPHONE (!IS_IPAD) #define IS_IPAD (UI_USER_INTERFACE_IDIOM() != UIUserInt ...
- 自定义控件出现“loaded nib but the view outlet was not set”
我出现这个错误是因为我的自定义控件的名字和项目中一个控制器的名字很像 控制器 DDGuessYourLikeViewController 自定义控件 DDGuessYourLikeView 默认的, ...
- IOS 真机调试以及发布应用 2
参考网站:http://my.oschina.net/u/1245365/blog/196420 已经有开发证书的直接跳过第一步 第一步:申请“开发证书” 进入苹果开发者99美元账号: 选择:Cert ...
- vim 支持gb2312
vi /etc/vimrc 中添加如下,并保存. set termencoding=encodingset fileencodings=utf-8,gbk,ucs-bom,cp936set shif ...
- 4位bcd数转换为2进制数
DATA SEGMENTBUF DW 1234HBUF1 DW ? ;2进制数放到buf1内存单元DATA ENDSCODE SEGMENTASSUME CS:CODE ...