URAL 1081. Binary Lexicographic Sequence(简单dp)

来源:互联网 发布:淘宝 赣南脐橙 编辑:程序博客网 时间:2024/05/16 18:12
题意:对于原有到二进制序列,规定连续两位为1的形式不合法,剩下的按字典序排列,如000合法但011不合法101合法。输入位数N和第几个数K输出其二进制形式,若无则输出-1
方法: DP关键在于找到状态转移方程,而找方程关键在于找状态。我们从限制条件开始构造状态。以位数N和K构造是不现实的,数据量太多,我们可以位数为N的二进制数的个数作为状态,这样如果第i位填0则f[i] = f[i-1] 如果第i位填1则第i-1位只能填0,此时f[i] = f[i-2]总之,f[i] = f[i-1] + f[i-2];这个就是传说中的转移方程。

然后考虑第K个的问题,因为开头为0的数必然排在开头为1的数的前面。也就是位数为N的数共有f[i]个,其中前面的是以0开头的f[i-1]个,后面是以1开头的f[i-2]个,所以如果K小于等于f[i-1]则其第i位必然为0,然后去考虑第i-1位,此时K不变;否则其第i位必然为1第i-1位必然为0,然后去考虑第i-2位,此时K= K-f[i-1]。

以上是别人写的说的很好,就没再写一遍啊。

PS;那个规律我是写出来的、、

1081. Binary Lexicographic Sequence

Time limit: 0.5 second
Memory limit: 64 MB
Consider all the sequences with length (0 < N < 44), containing only the elements 0 and 1, and no two ones are adjacent (110 is not a valid sequence of length 3, 0101 is a valid sequence of length 4). Write a program which finds the sequence, which is on K-th place (0 < K < 109) in the lexicographically sorted in ascending order collection of the described sequences.

Input

The first line of input contains two positive integers N and K.

Output

Write the found sequence or −1 if the number K is larger then the number of valid sequences.

Sample

inputoutput
3 1
000
#include <algorithm>#include <iostream>#include <stdlib.h>#include <string.h>#include <iomanip>#include <stdio.h>#include <string>#include <queue>#include <cmath>#include <stack>#include <map>#include <set>#define eps 1e-8#define M 1000100///#define LL __int64#define LL long long#define INF 0x3f3f3ff#define PI 3.1415926535898#define MOD 1000000009const int maxn = 40000005;using namespace std;LL num[maxn];void Printf(int kk, int len){    if(len >= 0)    {        if(kk > 0)        {            if(kk <= num[len])            {                cout<<0;                Printf(kk, len-1);            }            else            {                if(len > 0)                    cout<<10;                else                    cout<<1;                Printf(kk-num[len], len-2);            }        }    }}int main(){    num[0] = 1;    num[1] = 2;    num[2] = 3;    for(int i = 3; i < 44; i++)        num[i] = num[i-1]+num[i-2];    LL n, k;    while(cin >>n>>k)    {        if(k > num[n] || k < 1)        {            cout<<"-1"<<endl;            continue;        }        Printf(k, n-1);        cout<<endl;    }    return 0;}


0 0
原创粉丝点击