您的位置:首页 > 其它

HDU 2067 小兔的棋盘 递推/dp

2015-10-17 15:29 337 查看


小兔的棋盘

Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)

Total Submission(s): 7868    Accepted Submission(s): 4184


Problem Description

小兔的叔叔从外面旅游回来给她带来了一个礼物,小兔高兴地跑回自己的房间,拆开一看是一个棋盘,小兔有所失望。不过没过几天发现了棋盘的好玩之处。从起点(0,0)走到终点(n,n)的最短路径数是C(2n,n),现在小兔又想如果不穿越对角线(但可接触对角线上的格点),这样的路径数有多少?小兔想了很长时间都没想出来,现在想请你帮助小兔解决这个问题,对于你来说应该不难吧!

 

Input

每次输入一个数n(1<=n<=35),当n等于-1时结束输入。

 

Output

对于每个输入数据输出路径数,具体格式看Sample。

 

Sample Input

1
3
12
-1

 

Sample Output

1 1 2
2 3 10
3 12 416024

 

Author

Rabbit

 

Source

RPG专场练习赛

 

Recommend

lcy   |   We have carefully selected several similar problems for you:  2064 2065 1133 2068 1267 

问有多少种走法,因为不能穿过对角线所以分为两部分右上三角形和右下三角形

推出知道一半的走法是卡特兰数,卡特兰递推公式 f[0]=1;for i:1 to 40 f[i]=f[i-1]*(4*i-2)/(i+1);

起先用longlong 挂了不知道为什么

后来直接大数模板走起

ACcode:

#include <map>
#include <queue>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <stdlib.h>
#include <iostream>
#include <algorithm>
#define rd(x) scanf("%d",&x)
#define rd2(x,y) scanf("%d%d",&x,&y)
#define ll long long int
#define maxn 100005
#define mod 1000000007
#define INF 0x3f3f3f3f //int×î´óÖµ
#define FOR(i,f_start,f_end) for(int i=f_start;i<=f_end;++i)
#define MT(x,i) memset(x,i,sizeof(x))
#define PI  acos(-1.0)
#define E  exp(1)
#define MAXN 9999
#define MAXSIZE 1010
#define DLEN 4
using namespace std;
class BigNum{
private:
int a[500];
int len;
public:
BigNum(){len=1;MT(a,0);}
BigNum(const int);///int 转大数
BigNum(const char*);///字符转大数
BigNum(const BigNum&);///拷贝
BigNum &operator=(const BigNum&);///重载赋值
friend istream& operator>>(istream&,BigNum&);///重载输入
friend ostream& operator<<(ostream&,BigNum&);///输出
BigNum operator+(const BigNum&)const;
BigNum operator-(const BigNum&)const;
BigNum operator*(const BigNum&)const;
BigNum operator/(const int &)const;
BigNum operator^(const int &)const;///n次方
int operator%(const int &)const;///大数对Int数取mod
bool operator>(const BigNum &T)const;///比大小
bool operator>(const int &t)const;
void print();
};
BigNum ::BigNum(const int b){
int c,d=b;
len=0;
MT(a,0);
while(d>MAXN){
c=d-((d/MAXN+1))*(MAXN+1);
d=d/(MAXN+1);
a[len++]=c;
}
a[len++]=d;
}
BigNum::BigNum(const char *s){
int t,k,myindex,L,i;
MT(a,0);
L=strlen(s);
len=L/DLEN;
if(L%DLEN)len++;
myindex=0;
for(i=L-1;i>=0;i-=DLEN){
t=0;
k=i-DLEN+1;
if(k<0)k=0;
for(int j=k;j<=i;++j)
t=t*10+s[j]-'0';
a[myindex++]=t;
}
}
BigNum::BigNum(const BigNum &T):len(T.len){
MT(a,0);
for(int i=0;i<len;i++)
a[i]=T.a[i];
}
BigNum&BigNum::operator=(const BigNum &n){
len=n.len;
MT(a,0);
for(int i=0;i<len;i++)
a[i]=n.a[i];
return *this;
}
istream& operator>>(istream &in,BigNum &b){
char ch[MAXSIZE*4];
int i=-1;
in>>ch;
int L=strlen(ch);
int count=0,sum=0;
for(i=L-1;i>=0;){
sum=0;
int t=1;
for(int j=0;j<4&&i>=0;j++,i--,t*=10)
sum+=(ch[i]-'0')*t;
b.a[count]=sum;
count++;
}
b.len=count++;
return in;
}
ostream& operator<<(ostream& out,BigNum& b){
int i;
cout<<b.a[b.len-1];
for(i=b.len-2;i>=0;i--)
printf("%04d",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=0;i<big;++i){
t.a[i]+=T.a[i];;
if(t.a[i]>MAXN){
t.a[i+1]++;
t.a[i]-=MAXN+1;
}
}
if(t.a[big]!=0)
t.len=big+1;
else t.len=big;
return t;
}
BigNum BigNum::operator-(const BigNum &T)const{
int j,big;
bool flag;
BigNum t1,t2;
if(*this>T){
t1=*this;
t2=T;
flag=0;
}
else {
t1=T;
t2=*this;
flag=1;
}
big=t1.len;
for(int i=0;i<big;i++){
if(t1.a[i]<t2.a[i]){
j=i+1;
while(t1.a[j]==0)
j++;
t1.a[j--]--;
while(j>i)
t1.a[j--]+=MAXN;
t1.a[i]+=MAXN+1-t2.a[i];
}
else t1.a[i]-=t2.a[i];
}
t1.len=big;
while(t1.a[len-1]==0&&t1.len>1){
t1.len--;
big--;
}
if(flag)
t1.a[big-1]=0-t1.a[big-1];
return t1;
}
BigNum BigNum::operator*(const BigNum &T)const{
BigNum ret;
int i,j,up;
int temp,temp1;
for(i=0;i<len;i++){
up=0;
for(j=0;j<T.len;j++){
temp=a[i]*T.a[j]+ret.a[i+j]+up;
if(temp>MAXN){
temp1=temp-temp/(MAXN+1)*(MAXN+1);
up=temp/(MAXN+1);
ret.a[i+j]=temp1;
}
else {
up=0;
ret.a[i+j]=temp;
}
}
if(up!=0)
ret.a[i+j]=up;
}
ret.len=i+j;
while(ret.a[ret.len-1]==0&&ret.len>1)ret.len--;
return ret;
}
BigNum BigNum::operator/(const int &b)const{
BigNum ret;
int i,down=0;
for(i=len-1;i>=0;i--){
ret.a[i]=(a[i]+down*(MAXN+1))/b;
down=a[i]+down*(MAXN+1)-ret.a[i]*b;
}
ret.len=len;
while(ret.a[ret.len-1]==0&&ret.len>1)
ret.len--;
return ret;
}
int BigNum::operator%(const int &b)const{
int i,d=0;
for(i=len-1;i>=0;i--)
d=((d*(MAXN+1))%b+a[i])%b;
return d;
}
BigNum BigNum::operator^(const int &n)const{
BigNum t,ret(1);
int i;
if(n<0)exit(-1);
if(n==0)return 1;
if(n==1)return *this;
int m=n;
while(m>1){
t=*this;
for(i=1;(i<<1)<=m;i<<=1)
t=t*t;
m-=i;
ret=ret*t;
if(m==1)ret=ret*(*this);
}
return ret;
}
bool BigNum::operator>(const BigNum &T)const{
int ln;
if(len>T.len)return true;
else if(len==T.len){
ln=len-1;
while(a[ln]==T.a[ln]&&ln>=0)
ln--;
if(ln>=0&&a[ln]>T.a[ln])
return true;
else
return false;
}
else
return false;
}
bool BigNum::operator>(const int &t)const{
BigNum b(t);
return *this>b;
}
void BigNum::print(){
int i;
printf("%d",a[len-1]);
for(i=len-2;i>=0;i--)
printf("%04d",a[i]);
printf("\n");
}
BigNum my[110];
int main(){
my[0]=1;
for(int i=1;i<40;++i)
my[i]=my[i-1]*(4*i-2)/(i+1);
for(int i=1;i<40;++i)
my[i]=my[i]*2;
int n,cnt=1;
while(rd(n)&&n!=-1){
printf("%d %d ",cnt++,n);
my
.print();
}
return 0;
}

/*
1
3
12
-1
*/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: