ural Binary Lexicographic Sequence (dp + dfs)

http://acm.timus.ru/problem.aspx?space=1&num=1081

有一个二进制序列,定义为不能有两个连续的1出现,才是合法的。给出序列的长度n,求合法的二进制序列中按字典序排序后第k个序列是什么。

设dp[i][0]和dp[i][1]分别表示第i位上是0和1的个数。

那么dp[i][0] = dp[i-1][0] + dp[i-1][1];dp[i][1] = dp[i-1][0],打表发现和斐波那契数列相似。

求第k个合法的序列时,因为是按字典序排序,可以发现当 k >= dp[n-1]时这一位取1,否则这一位取0。

#include <stdio.h>
#include <iostream>
#include <map>
#include <set>
#include <list>
#include <stack>
#include <vector>
#include <math.h>
#include <string.h>
#include <queue>
#include <string>
#include <stdlib.h>
#include <algorithm>
#define LL __int64
#define eps 1e-12
#define PI acos(-1.0)
using namespace std;
const int INF = 0x3f3f3f3f;
const int maxn = 4010;

int dp[50][2],tmp[50];
void init()
{
	memset(dp,0,sizeof(dp));
	dp[1][0] = dp[1][1] = 1;
	tmp[1] = 2;
	for(int i = 2; i < 44; i++)
	{
		dp[i][0] += (dp[i-1][0] + dp[i-1][1]);
		dp[i][1] += dp[i-1][0];
		tmp[i] = dp[i][0] + dp[i][1];
	}
}

void dfs(int n, int k)
{
	if(n == 1)
	{
		if(k == 1)
			printf("0");
		else
			printf("1");
		return;
	}
	if(k <= tmp[n-1])
	{
		printf("0");
		dfs(n-1,k);
	}
	else
	{
		printf("1");
		dfs(n-1,k-tmp[n-1]);
	}
}

int main()
{
	init();
	int n,k;
	while(~scanf("%d %d",&n,&k))
	{
		if(k > tmp[n])
		{
			printf("-1\n");
			continue;
		}
		dfs(n,k);
		printf("\n");
	}
	return 0;
}
时间: 2024-08-08 19:03:17

ural Binary Lexicographic Sequence (dp + dfs)的相关文章

递推DP URAL 1081 Binary Lexicographic Sequence

题目传送门 1 /* 2 dp[i][1]/dp[i][0] 表示从左往右前i个,当前第i个放1或0的方案数 3 k -= dp[n][0] 表示当前放0的方案数不够了,所以必须放1,那么dp[n][0]个方案数都不能用了 4 相当于k减去这么多 5 详细解释:http://www.cnblogs.com/scau20110726/archive/2013/02/05/2892587.html 6 */ 7 #include <cstdio> 8 #include <algorithm&

URAL 1081 Binary Lexicographic Sequence

第13个位置第5个Bit :13>num[4] =>1 第四个bit 13-num[4]=5 :5<num[3] =>0 ,3-1 第三个Bit 5>num[2](3) 5-num[2]=2 ... #include<stdio.h> int num[45]; void init() { num[0]=1; num[1]=2; int k=2; while(k<44) { num[k]=num[k-1]+num[k-2]; k++; } } int main

URAL1081 Binary Lexicographic Sequence(递归)

URAL 1081. Binary Lexicographic Sequence Time limit: 0.5 second Memory limit: 64 MB Description 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 l

Ural 1081 Binary Lexicographic Sequence(DP)

题目地址:Ural 1081 先用dp求出每个长度下的合法序列(开头为1)的个数.然后求前缀和.会发现正好是一个斐波那契数列.然后每次判断是否大于此时长度下的最少个数,若大于,说明这一位肯定是1,若小于,则肯定是0.就这样不断输出出来即可. 代码如下: #include <iostream> #include <cstdio> #include <string> #include <cstring> #include <stdlib.h> #in

URAL1081——DP—— Binary Lexicographic Sequence

Description 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 seq

Binary Lexicographic Sequence URAL - 1081 (有关数的排列)

1 #include<iostream> 2 #include<vector> 3 #include<algorithm> 4 #include<map> 5 #include<set> 6 #include<string> 7 using namespace std; 8 typedef unsigned long long LL; 9 const int maxn = 46; 10 LL dp[maxn][2]; 11 12 vo

URAL 1183 Brackets Sequence DP 路径输出

题意:长度小于100的字符串s只由四种字符"()[]"组成,求以该串为子串的最短的合法串.合法串递归定义为: (1)空串合法 (2)如果S合法,则(S).[S]合法 (3)如果A.B合法,则AB合法 思路: 设dp[i][j]为s(i,j)变为合法串后,合法串的长度或需要添加的字符的个数,状态转移: (1)如果s[i]和s[j]匹配,dp[i,j]=dp[i+1,j-1]. (2)如果不匹配,划分s(i,j)为s(i,k)和s(k+1,j),划分后dp[i,j]=dp[i,k]+dp[

记忆化搜索+DFS URAL 1183 Brackets Sequence

题目传送门 1 /* 2 记忆化搜索+DFS:dp[i][j] 表示第i到第j个字符,最少要加多少个括号 3 dp[x][x] = 1 一定要加一个括号:dp[x][y] = 0, x > y; 4 当s[x] 与 s[y] 匹配,则搜索 (x+1, y-1); 否则在x~y-1枚举找到相匹配的括号,更新最小值 5 */ 6 #include <cstdio> 7 #include <algorithm> 8 #include <cmath> 9 #include

POJ 1699 Best Sequence(DFS)

題目鏈接 題意 : 將幾個片段如圖所示方法縮成一個序列,求出最短這個序列. 思路 : 其實我也不知道怎麼做.....看網上都用了DP.....但是我不會.....這個DP不錯,還有用KMP+状压DP做的 1 //1699 2 #include <iostream> 3 #include <stdio.h> 4 #include <string.h> 5 #include <string> 6 7 using namespace std; 8 9 string