UVa 10359 - Tiling

题目:给你一个2*n的地面,用1*2和2*2的地板砖铺满,有多少种不同方案。

分析:组合数学,动态规划。直接找到地推关系求解。

因为,只可能是最后一列是一个整体(1种情况)或者最后两列是一个整体(两种情况);

所以,有递推公式:f(n)= f(n-1)+ 2*f(n-2);

可以使用动态规划或母函数(an = (pow(2,n+1)-pow(-1,n+1))/ 3)求解。

说明:大整数运算,这里采用dp求解,貌似快速幂会快点╮(╯▽╰)╭。

#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <cmath>

using namespace std;

int ans[255][101],two[101];

void copy_array(int *a, int *b)
{
	for (int i = 0; i < 100; ++ i)
		a[i] = b[i];
}

void add_array(int *c, int *a, int *b)
{
	for (int i = 0; i < 100; ++ i)
		c[i] = 0;
	for (int i = 0; i < 100; ++ i) {
		c[i] += a[i]+b[i];
		if (c[i] > 9) {
			c[i+1] += c[i]/10;
			c[i] %= 10;
		}
	}
}

void output_array(int *a)
{
	int end = 100;
	while (end && !a[end]) -- end;
	while (end >= 0) printf("%d",a[end --]);
	printf("\n");
}

int main()
{
	memset(ans, 0, sizeof(ans));
	ans[0][0] = 1;ans[1][0] = 1;
	for (int i = 2; i < 252; ++ i) {
		add_array(two, ans[i-2], ans[i-2]);
		add_array(ans[i], ans[i-1], two);
	}

	int n;
	while (~scanf("%d",&n))
		output_array(ans[n]);

    return 0;
}
时间: 2024-10-19 23:25:39

UVa 10359 - Tiling的相关文章

uva 11270 - Tiling Dominoes(插头dp)

题目链接:uva 11270 - Tiling Dominoes 题目大意:用1?2木块将给出的n?m大小的矩阵填满的方法总数. 解题思路:插头dp的裸题,dp[i][s]表示第i块位置,并且该位置对应的行数的状态为s的时候的总情况数.0表示为竖放预留留的位置,1表示填上的位置,不管是竖放还是横放.并且第一位状态用滚动数组优化空间. #include <cstdio> #include <cstring> #include <algorithm> using names

【UVa】Tiling Dominoes

http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=2245 题意:求用1×2的棋子摆满n×m的棋盘的方案数.(n×m<=100) #include <bits/stdc++.h> using namespace std; long long d[2][1<<10], n, m; int main() { while

UVA 11270 Tiling Dominoes(轮廓线DP经典)

题意:用1*2的骨牌覆盖n*m的棋盘有多少种方法 这道题注意一下不要按照大白书上把maxn开成15就好,因为每次都要memset如果开到15会tle,开到11就可以 #include<cstdio> #include<cstring> #include<cmath> #include<cstdlib> #include<iostream> #include<algorithm> #include<vector> #incl

UVA 11270 Tiling Dominoes

https://vjudge.net/problem/UVA-11270 题目 用$1\times2$骨牌覆盖$n\times m$棋盘,有多少种方法? $n\times m<101$ 题解 棋盘已经填了的部分只能用考虑轮廓线表示清楚,不能只用行和列.轮廓线总共有$2^{宽}$种状态,因此需要把宽度尽量缩小. 令$n\leqslant m$,可以得到$n\leqslant 10$,所以轮廓线的状态有$2^{10}$种. 只在轮廓线的右下角放骨牌,并且保证轮廓线的上面是完全填满了的.比如下图这样的

UVA题目分类

题目 Volume 0. Getting Started 开始10055 - Hashmat the Brave Warrior 10071 - Back to High School Physics 10300 - Ecological Premium 458 - The Decoder 494 - Kindergarten Counting Game 414 - Machined Surfaces 490 - Rotating Sentences 445 - Marvelous Mazes

UVa 10918 - Tri Tiling

题目:给你一个3*n的地面,用1*2的地板砖铺满,问有几种方法. 分析:组合数学,动态规划.首先找到地推关系. 只有偶数才有意义,奇数的总面积为奇数一定不成立.一次我们以两列为一个单位考察. 如果,最后2列构成一个整体的部分(3种情况,2*3的3中实现),则有3*f(n-2)种方法: 如果,最后4列构成一个整体的部分(2种情况,上下翻转实现),则有2*f(n-4)种方法: ... 因此,有递推公式: f(n)= 3*f(n-2)+ 2(f(n-4)+ f(n-6)+ ...): 整理化简可以得到

UVA 562 Dividing coins --01背包的变形

01背包的变形. 先算出硬币面值的总和,然后此题变成求背包容量为V=sum/2时,能装的最多的硬币,然后将剩余的面值和它相减取一个绝对值就是最小的差值. 代码: #include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <algorithm> using namespace std; #define N 50007 int c[102],d

UVA 10341 Solve It

Problem F Solve It Input: standard input Output: standard output Time Limit: 1 second Memory Limit: 32 MB Solve the equation: p*e-x + q*sin(x) + r*cos(x) + s*tan(x) + t*x2 + u = 0 where 0 <= x <= 1. Input Input consists of multiple test cases and te

UVA 11014 - Make a Crystal(容斥原理)

UVA 11014 - Make a Crystal 题目链接 题意:给定一个NxNxN的正方体,求出最多能选几个整数点.使得随意两点PQ不会使PQO共线. 思路:利用容斥原理,设f(k)为点(x, y, z)三点都为k的倍数的点的个数(要扣掉一个原点O).那么全部点就是f(1),之后要去除掉共线的,就是扣掉f(2), f(3), f(5)..f(n).n为素数.由于这些素数中包括了合数的情况,而且这些点必定与f(1)除去这些点以外的点共线,所以扣掉.可是扣掉后会扣掉一些反复的.比方f(6)在f