您的位置:首页 > 其它

uva 11125 - Arrange Some Marbles(记忆化搜索)

2013-11-14 20:19 323 查看
题目链接:uva 11125 - Arrange Some Marbles

题目大意:给出n表示有n种颜色的大理石,然后a1~an,表示各种颜色的大理石有多少个,然后现在要将大理石排成一排,颜色相同的的为一组,相邻的两组颜色和大小不能相同,而且头尾两组的大小和颜色也不能相同,问说有多少排列的方式。

解题思路:一开始被题意搞蒙了,其实记忆化搜索就可以了,开一个5维数组,rec[bc][bn][x][y][t],bc,bn分别为第一组的颜色和大小,x,y分别为前一组的颜色和大小,t为压缩的各种颜色大理石的余量。

#include <stdio.h>
#include <string.h>

const int N = 8;
const int MAXN = 4500;

int n, a
, bc, bn;
int rec

[MAXN];

int dp(int x, int y, int s) {

int t = 0;
for (int i = 0; i < 4; i++)
t = t * 8 + a[i];

if (!s) {
if (x != bc && y != bn) return 1;
else return 0;
}

int& ans = rec[bc][bn][x][y][t];
if (ans != -1) return ans;
ans = 0;

for (int i = 0; i < n; i++) {
if (i == x) continue;
for (int j = 1; j <= 3 && j <= a[i]; j++) {
if (j == y) continue;
a[i] -= j;
ans += dp(i, j, s - j);
a[i] += j;
}
}
return ans;
}

int solve() {
int s = 0, ans = 0;
scanf("%d", &n);
memset(a, 0, sizeof(a));
for (int i = 0; i < n; i++) {
scanf("%d", &a[i]);
s += a[i];
}

if (!s) return 1;

for (int i = 0; i < n; i++) {
for (int j = 1; j <= 3 && j <= a[i]; j++) {
bc = i, bn = j;
a[i] -= j;
ans += dp(i, j, s - j);
a[i] += j;
}
}
return ans;
}

int main () {
int cas;
scanf("%d", &cas);
memset(rec, -1, sizeof(rec));
while (cas--) {
printf("%d\n", solve());
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: