HDU 1041 Computer Transformation 数学DP题解

本题假设编程是使用DP思想直接打表就能够了。

假设是找规律就须要数学思维了。

规律就是看这些连续的0是从哪里来的。

我找到的规律是:1经过两次裂变之后就会产生一个00; 00经过两次裂变之后也会产生新的00;故此须要记录好1和00出现的次数就能够递推出后面的00出现的数据了。

公式就是tbl00[i] = tbl00[i-2] + tbl1[i-2]; 当中tbl00是记录00出现的次数,tbl1是出现1出现的次数。

公式事实上是能够化简的,只是我懒得化简了。这种公式非常清楚了。

只是因为这种数极大。故此就须要用到大数运算了。

#include <stdio.h>
#include <vector>
#include <string.h>
#include <algorithm>
#include <iostream>
#include <string>
#include <limits.h>
#include <stack>
#include <queue>
#include <set>
#include <map>
using namespace std;

const short MAX_N = 1001;
vector<short> tbl00[MAX_N], tbl1[MAX_N];//inverse saved numbers

void plusLarge(vector<short> &c, vector<short> &a, vector<short> &b)
{
	short n = (short)a.size(), m = (short)b.size(), carry = 0;
	for (short k = 0, d = 0; k < n || d < m || carry; k++, d++)
	{
		short s1 = k < n?

a[k] : 0;
		short s2 = d < m? b[d] : 0;
		carry = s1 + s2 + carry;
		c.push_back(carry % 10);
		carry /= 10;
	}
}

void genTbl()
{
	tbl00[0].push_back(0), tbl1[0].push_back(1);
	tbl00[1].push_back(0), tbl1[1].push_back(1);
	tbl00[2].push_back(1), tbl1[2].push_back(2);
	for (short i = 3; i < MAX_N; i++)
	{
		plusLarge(tbl00[i], tbl00[i-2], tbl1[i-2]);
		plusLarge(tbl1[i], tbl1[i-1], tbl1[i-1]);
	}
}

int main()
{
	genTbl();
	int n;
	while (scanf("%d", &n) != EOF)
	{
		vector<short> &a = tbl00[n];
		short m = (short)a.size();
		for (short i = m-1; i >= 0; i--)
		{
			printf("%d", a[i]);
		}
		putchar(‘\n‘);
	}
	return 0;
}
时间: 2024-08-07 04:14:59

HDU 1041 Computer Transformation 数学DP题解的相关文章

HDU 1041[Computer Transformation] 递推 高精度

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1041 题目大意:初始数字1.规则1变成01,0变成10.问经过N次完整变换后,有多少连续零对. 关键思想:考虑零对的直接来源只有"10",而"10"的直接来源只有"1"或者"00".于是可以得到以下几种递推式 1. dp[i]=pow(2,i-3)+dp[i-2];当前层多少1,下一层就多少10,下下层就多少00:当前层多少00,

HDU 1041 Computer Transformation(找规律加大数乘)

主要还是找规律,然后大数相乘 #include<stdio.h> #include<string.h> #include<math.h> #include<time.h> #include<map> #include<iostream> #include<ctype.h> #include<string> #include<algorithm> #include<stdlib.h> #i

HDU 1231 最大连续子序列 DP题解

典型的DP题目,增加一个额外要求,输出子序列的开始和结尾的数值. 增加一个记录方法,nothing special. 记录最终ans的时候,同时记录开始和结尾下标: 更新当前最大值sum的时候,更新开始节点. const int MAX_N = 10001; long long arr[MAX_N]; int N, sta, end; long long getMaxSubs() { long long sum = 0, ans = LLONG_MIN; int ts = 0; for (int

HDU 1160 FatMouse&#39;s Speed DP题解

本题就先排序老鼠的重量,然后查找老鼠的速度的最长递增子序列,不过因为需要按原来的标号输出,故此需要使用struct把三个信息打包起来. 查找最长递增子序列使用动态规划法,基本的一维动态规划法了. 记录路径:只需要记录后继标号,就可以逐个输出了. #include <stdio.h> #include <algorithm> using namespace std; const int MAX_N = 1005; struct MouseSpeed { int id, w, s; b

HDU 2196 Computer 经典树形DP

一开始看错题了,后来发现原来是在一颗带权的树上面求出距离每一个点的最长距离,做两次dfs就好,具体的看注释? #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> #include <climits> #include <string> #include <iostream> #include <map> #incl

题解报告:hdu 2196 Computer(树形dp)

Problem Description A school bought the first computer some time ago(so this computer's id is 1). During the recent years the school bought N-1 new computers. Each new computer was connected to one of settled earlier. Managers of school are anxious a

HDU 1069 Monkey and Banana dp 题解

HDU 1069 Monkey and Banana 题解 纵有疾风起 题目大意 一堆科学家研究猩猩的智商,给他M种长方体,每种N个.然后,将一个香蕉挂在屋顶,让猩猩通过 叠长方体来够到香蕉. 现在给你M种长方体,计算,最高能堆多高.要求位于上面的长方体的长要大于(注意不是大于等于)下面长方体的长,上面长方体的宽大于下面长方体的宽. 输入输出 开始一个数n,表示有多少种木块,木块的数量无限,然后接下来的n行,每行3个数,是木块的长宽高三个参量 输出使用这些在满足条件的情况下能够摆放的最大高度 解

HDU 2196 Computer(树形DP求最长路)

Problem Description A school bought the first computer some time ago(so this computer's id is 1). During the recent years the school bought N-1 new computers. Each new computer was connected to one of settled earlier. Managers of school are anxious a

hdu 2196 computer 树状dp

Computer Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 3731    Accepted Submission(s): 1886 Problem Description A school bought the first computer some time ago(so this computer's id is 1). Du