Camels【DP】

题目链接
Bob likes to draw camels: with a single hump, two humps, three humps, etc. He draws a camel by connecting points on a coordinate plane. Now he’s drawing camels with t humps, representing them as polylines in the plane. Each polyline consists of n vertices with coordinates (x1, y1), (x2, y2), …, (xn, yn). The first vertex has a coordinate x1 = 1, the second — x2 = 2, etc. Coordinates yi might be any, but should satisfy the following conditions:

there should be t humps precisely, i.e. such indexes j (2 ≤ j ≤ n - 1), so that yj - 1 < yj > yj + 1,
there should be precisely t - 1 such indexes j (2 ≤ j ≤ n - 1), so that yj - 1 > yj < yj + 1,
no segment of a polyline should be parallel to the Ox-axis,
all yi are integers between 1 and 4.
For a series of his drawings of camels with t humps Bob wants to buy a notebook, but he doesn’t know how many pages he will need. Output the amount of different polylines that can be drawn to represent camels with t humps for a given number n.

Input

The first line contains a pair of integers n and t (3 ≤ n ≤ 20, 1 ≤ t ≤ 10).

Output

Output the required amount of camels with t humps.

Examples

Input

6 1

Output

6

Input

4 2

Output

0

Note

In the first sample test sequences of y-coordinates for six camels are: 123421, 123431, 123432, 124321, 134321 и 234321 (each digit corresponds to one value of yi).

题意

给你两个整数n和t,构造一个长度为n的序列a,且满足:

  1. 元素是1~4之间的整数
  2. 有且只有t个a[i]满足 a[i-1] < a[i] > a[i+1](2<=i<=n-1)
  3. 有且只有(t-1)个a[i]满足a[i-1] > a[i] < a[i+1](2<=i<=n-1)
  4. a[1]<a[2]&&a[n-1]>a[n]
  5. a[i]!=a[i+1]

求方案数。

思路

由于n和t都十分的小,我们很容易想到打表,咳咳。。
我们很容易想到DP ,咳咳。。
好吧,其实啥都想不到。
观察一下,再根据平时经验,像求方案数什么的一般都是dp题,于是就理所应当的dp了。
既然是dp,那么就理所应当的有着状态定义与状态转移方程式了。

想一想,构造题的dp中的维度中一般都有一维是下标。
想想转移:条件太少,转移不了。

既然有一维下标,对应的就有其状态,而此题要求恰好可以当维度。
于是就有两个或多个维度之间有关系:

  1. 而由于此题给出了t,则又有一维当驼峰,表示第i个数在第k个驼峰上。
    想想转移:则1(i-1)之间的元素,在(1k)个驼峰上,方案数从[i-1][k]与[i-1][k-1]转移。
    但既不知道其状态,又不知道如何转。
  2. 而由于此题给出了元素范围,则又有一维当大小,表示第i个数值为j。
    想想转移:f[i][j][k]与f[i-1][r][k]。则转移必定要用到j与r之间的大小关系:
    f[i][j][k]=f[i-1][1(j-1)][k]+f[i-1][(j+1)4][k];但在处理答案时要求a[n-1]>a[n],故会加上不合法状态。
  3. 而由于此题给出a[n-1]>a[n],我们可以再加上一维r(1/0)来表示此元素与上一元素相比是上升还是下降。
    想想转移:
    f[i][j][k][0]=f[i-1][(j+1)4][k][0]+f[i-1][(j+1)4][k][1];//(i-1)上升与下降都与i在同一驼峰。
    f[i][j][k][1]=f[i-1][1(j-1)][k][1]+f[i-1][1(j-1)][k-1][0];//(i-1)上升时在同一驼峰,下降时则处于两驼峰交界处。

这里并不是构造而是分类
以上思路复杂,以下是结果

//dp[i][j][k][r] 第i个数为j时在第k个驼峰上处于 r=1上升,r=0下降 状态的方案数

代码

#include<cstdio>
#include<algorithm>
using namespace std;
const int MAXN=20,MAXT=10,MAXK=4,MAXR=2;
int n,t,f[MAXN+2][MAXK+2][MAXT+2][MAXR+2];
int Ans;
int main(){
	scanf("%d%d",&n,&t);
	f[2][2][1][1]=1;
	f[2][3][1][1]=2;
	f[2][4][1][1]=3;
	for(int i=3;i<=n;i++)
		for(int j=1;j<=4;j++)
			for(int k=1;k<=t;k++){
				for(int r=4;r>j;r--)
					f[i][j][k][0]+=f[i-1][r][k][0]+f[i-1][r][k][1];
				for(int r=1;r<j;r++)
					f[i][j][k][1]+=f[i-1][r][k][1]+f[i-1][r][k-1][0];
			}
	for(int i=1;i<=MAXK;i++)
		Ans+=f[n][i][t][0];
	printf("%d\n",Ans);
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值