XTU1398积木II

菜鸡一个,写一些网上找不到的oj叭,造福一下下一届

题目描述

n个积木,分成m垛,这些积木垛排成一行,使得所有垛的积木块数不相同,且呈“山“字形(积木数先单调上升,再单调下降)。比如6块积木,分成3垛,只有132,231两种方案。 现在已知n,m,请求方案数。

输入

第一行是一个整数T(1≤T≤1000),表示样例的个数。

以后每行两个整数n(3≤n≤100),m(3≤m≤10)。

输出

每行是输出一个样例的个数。

样例输入

2
6 3
9 3

样例输出

2
6

样例解释

第二个样例,分别为”162”,”153”,”243”,”261”,”351”,”342”。

相信做到这题的话Blocks应该已经做过了,这题其实就是在Blocks上用了一点点数学的思想。不多说了,放代码,代码风格有点丑(见谅)

#include<stdio.h>
#include<string.h>
#include<math.h>
#include<bits/stdc++.h>
using namespace std;

int main() {
	int t;
	int i, j, k, l, n, m,sum;
	scanf("%d", &t);
	while (t--) {
		int a[101][11][110];//a[i][j][k]为i块积木,共j列,第一列为k个方块的方案数
		memset(a, 0, sizeof(a));
		a[1][1][1] = 1;
		scanf("%d %d", &n, &m);
		for (i = 2; i <= n; i++) {
			for (j = 1; j <= m; j++) {
				for (k = 1; k <= i; k++) {
					if (i == k && j == 1) { //如果排成一列,第一列为总积木时,只有一种情况 
						a[i][j][k] = 1;
					} else {
						for (l = k - 1; l >= 1; l--) {
							a[i][j][k] += a[i - k][j - 1][l];
						}
					}
				}
			}//排几列
		}
		sum = 0;
		for (i = 1; i <= n; i++) {
			sum += a[n][m][i];
		}
		sum=sum*(pow(2,m-1)-2);
		printf("%d\n", sum);
	}
	return 0;
}

相比于Block那道题,我只是加了一个

sum=sum*(pow(2,m-1)-2);

这里就是和积木Ⅰ不一样的地方,因为单调性要分布两边,相当于把已经搭好的积木排列组合,除了最高的一列, 每一列可以在前面或者后面,相当于X2,所以就是2^(m-1),再减去两种单调的情况。

还是谢大放水了hhh

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值