HDOJ 1041 (推公式,大数)水题

Computer Transformation

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 9152    Accepted Submission(s): 3416

Problem Description

A sequence consisting of one digit, the number 1 is initially written into a computer. At each successive time step, the computer simultaneously tranforms each digit 0 into the sequence 1 0 and each digit 1 into the sequence 0 1. So, after the first time step, the sequence 0 1 is obtained; after the second, the sequence 1 0 0 1, after the third, the sequence 0 1 1 0 1 0 0 1 and so on. 
How many pairs of consequitive zeroes will appear in the sequence after n steps? 

Input

Every input line contains one natural number n (0 < n ≤1000).

Output

For each input n print the number of consecutive zeroes pairs that will appear in the sequence after n steps.

Sample Input

2 3

Saple Output

1 1

Source

Southeastern Europe 2005

 题解:

这题我发现网上的公式都推的莫名其妙,应该都是找规律的。

然后我自己推了一遍,发现我推出来的公式有点不同。

因为1->01,00->1010。

01 -> 1001

所以C(n)只与C(n-2) 的1的个数和 00 的个数有关,而00的个数就是C(n-2),

故列出C(n)=C(n-2)+2^(n-3);

所以   C(n-1)=C(n-3)+2^(n-4),再代入得

故列出C(n)=C(n-1)*2+ C(n-2) - 2*C(n-3);好了。

插入代码(要注意大数处理中有一个减法,需要另外判断)

#include<iostream>
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int f[1001][400];
void bigdigit()
{
    f[1][0]=0;
    f[2][0]=1;
    f[3][0]=1;
    for(int i=4;i<=1000;i++)
        for(int j=0,b=0;j<=400;j++)
		{
            f[i][j]=b+f[i-1][j]*2+f[i-2][j]-2*f[i-3][j];
            if(f[i][j]<0) 
			f[i][j]+=10,b= -1;
			else 
			b=f[i][j]/10,f[i][j]%=10;
        }
}
int main()
{
    memset(f,0,sizeof(f));
    int n;
    bigdigit();
    while(cin>>n)
    {
        int i;
        if(n==1)
        cout<<"0"<<endl;
        else
        {
            for( i=399;i>=0;i--)
            if(f[n][i]!=0)
            break;
            for(int j=i;j>=0;j--)
            cout<<f[n][j];
            cout<<endl;
        }
    }
    return 0;
}

 

posted @ 2018-07-27 09:51  AshK  阅读(156)  评论(0编辑  收藏  举报