Codeforces Round #117 (Div. 2) E. Wooden Fence

题意

    给了 n 种类型的木板,每种类型的木板数量无限,可以随意旋转,现在要用这些木板组成一个 fence,fence 的长度必须刚好是 L,并且需要满足两个要求:
        1、相邻的木板不能同种类
        2、前一个板子的宽度必须是后一个板子的长度
    现在问你能组成多少种 fence 满足上面的条件

做法分析

    动态规划,长度类型的,以长度划分阶段,每个阶段的状态可以这样定义:f[L][[i] 表示已经拼凑成了一个长度为 L 的,最后一个木板是第 i 个,有多少种不同的fence。这里需要做一个处理:如果一个木板的长度和宽度不等,那么,就再生成一个木板,这个木板的宽度是原来木板的长度,长度是原来木板的宽度,类型和原来的木板类型相同,所以便有了上面的阶段划分和状态转移

AC通道

Codeforces Round #117 (Div. 2) E. Wooden Fence

参考代码

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

using namespace std;

const int N=250;
const int MOD=1000000007;

struct data
{
	int type;
	int width, length;
} a[N];

int f[3050][250], n, cnt, m;

int main()
{
	memset(f, 0, sizeof(f));
	scanf("%d%d", &n, &m);
	cnt=n;
	for(int i=1, L, W; i<=cnt; i++)
	{
		scanf("%d%d", &L, &W);
		a[i].length=L, a[i].width=W, a[i].type=i;
		f[L][i]=(f[L][i]+1)%MOD;
		if(L!=W)
		{
			n++;
			a[n].length=W, a[n].width=L, a[n].type=i;
			f[W][n]=(f[W][n]+1)%MOD;
		}
	}
	for(int L=0; L<=m; L++)
		for(int i=1; i<=n; i++)
			for(int j=1; j<=n; j++)
				if(a[i].type!=a[j].type && a[j].width==a[i].length && L>=a[i].length)
				{
					f[L][i]=(f[L][i]+f[L-a[i].length][j])%MOD;
				}
	int ans=0;
	for(int i=1; i<=n; i++)
		ans=(ans+f[m][i])%MOD;
	printf("%d\n", ans);
	return 0;
}


你可能感兴趣的:(Codeforces Round #117 (Div. 2) E. Wooden Fence)