DP之八

//sicily 1166. Computer Transformat

#include
<iostream> //DP+高精度
using namespace std;
#define M 50
int Bit(int p)
{
if(p==0)
return 1;
int bit=0;
while(p!=0)
{
p
/=10;
bit
++;
}
return bit;
}
class Longint //高精度
{
public:
Longint()
{
for(int i=0;i<M;++i)
num[i]
=0;
}
Longint(
int m)
{
for(int i=0;i<M-1;++i)
num[i]
=0;
num[M
-1]=m;
}
Longint
operator =(Longint other)
{
for(int i=0;i<M;++i)
num[i]
=other.num[i];
return *this;
}
friend Longint
operator +(Longint p,Longint other)
{
Longint p1;
int bit=0;
for(int i=M-1;i>=0;--i) //数组开得足够大,靠前的几个num[i]将一直是0,所以不必考虑第一个数向前进位的问题
{
p1.num[i]
=p.num[i]+other.num[i]+bit;
if(p1.num[i]>=1000000000)
{
p1.num[i]
=p1.num[i]-1000000000;
bit
=1;
}
else
bit
=0;
}
return p1;
}
friend ostream
& operator <<(ostream& out,Longint& p)
{
int i=0;
while(i<M&&p.num[i]==0)
++i;
if(i==M)
out<<0;
else
{
out<<p.num[i];
for(int j=i+1;j<M;++j)
{
int k=9-Bit(p.num[j]);
while(k--)
out<<0;
out<<p.num[j];
}
}
return out;
}
private:
int num[M];
};

Longint dp[
1010][2]; //dp[i][0]表示第i轮后有多少个 01 , dp[i][1]表示第i轮后有多少个 1
int main()
{
dp[
0][0]=Longint(0);dp[0][1]=Longint(1); //初始值是1,所以dp[0][0]=0, dp[0][1]=1
dp[1][0]=dp[1][1]=Longint(1); //第一轮是01,所以dp[1][0]= dp[1][1]=1
for(int i=2;i<=1000;++i)
{
dp[i][
0]=dp[i-1][1]+dp[i-2][0];
dp[i][
1]=dp[i-1][1]+dp[i-1][1]; //dp[i][1]=2^(i-1)
}
int n;
while(cin>>n)
{
cout
<<dp[n-1][0]<<endl;
}
return 0;
}

/*
题意:一开始只有一个1,然后每一轮把1变为01,把0变为10,问经过N轮后有多少个00。
例如,第一轮后变为01,第二轮后变为1001,第三轮后变为01101001。

思路:
由于00只能由01变化得到,01->1001,所以要知道第N轮后有多少个00,需要知道第N-1轮后有多少个01
01有两种方法生成:由上一轮的 1 生成,即1->01, 或者由上一轮的 00 生成,即 00->1010(含01)
事实上,在第二种方法中,上一轮的 00 是由前一轮的 01 生成,即 01->1001(含00)
所以推导出 dp[i][0]=dp[i-1][1]+dp[i-2][0]; ( dp[i][0]表示第i轮后有多少个 01 , dp[i][1]表示第i轮后有多少个 1 )
至于dp[i][1],显然有 dp[i][1]=2^(i-1)
*/

  

posted on 2011-08-22 12:15  sysu_mjc  阅读(152)  评论(0编辑  收藏  举报

导航