您的位置:首页 > 其它

SPOJ AEROLITE

2016-02-03 11:15 232 查看
题目链接: http://www.spoj.com/problems/AEROLITE/en/

--------------------------------------------------------------------------------------

虽然没有明确的区间,但做法还是和区间$DP$一样, 将左右两个区间合并成一个大区间

为了防止重复统计,每次左区间必须是有一个括号括在最外层的

自己做的方法的复杂度可达 $O((L1L2L3D)^2)$ 加上少量剪枝后仍有$3s$

#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
const int mod = 11380;
long long f[12][12][12][32];
long long dfs(int l1, int l2, int l3, int d)
{
if(f[l1][l2][l3][d] != -1)
return f[l1][l2][l3][d];
if(l1 + l2 + l3 == 0)
return f[l1][l2][l3][d] = (d == 0);
if(l1 + l2 + l3 < d)
return f[l1][l2][l3][d] = 0;
f[l1][l2][l3][d] = 0;
for(int b1 = 0; b1 <= l1; ++ b1)
for(int b2 = 0; b2 <= l2; ++ b2)
for(int b3 = 0; b3 <= l3; ++ b3)
{
if(b1 + b2 + b3 == 0)
continue;
for(int d1 = 1; d1 < d ; ++d1)
{
if(b1)
f[l1][l2][l3][d] += dfs(b1 - 1, b2, b3,
d1 - 1) * dfs(l1 - b1, l2 - b2, l3 - b3, d);
else if(b2)
f[l1][l2][l3][d] += dfs(0, b2 - 1, b3, d1 - 1)
* dfs(l1, l2 - b2, l3 - b3, d);
else
f[l1][l2][l3][d] += dfs(0, 0, b3 - 1, d1 - 1)
* dfs(l1, l2, l3 - b3, d);
}
for(int d2 = 0; d2 <= d; ++d2)
{
if(b1)
f[l1][l2][l3][d] += dfs(b1 - 1, b2, b3,
d - 1) * dfs(l1 - b1, l2 - b2, l3 - b3, d2);
else if(b2)
f[l1][l2][l3][d] += dfs(0, b2 - 1, b3, d - 1)
* dfs(l1, l2 - b2, l3 - b3, d2);
else
f[l1][l2][l3][d] += dfs(0, 0, b3 - 1, d - 1)
* dfs(l1, l2, l3 - b3, d2);
}
}
return f[l1][l2][l3][d] %= mod;
}
int main()
{
int l1, l2, l3, d;
for(int ca = 1; ca <= 10; ++ca)
{
memset(f, -1, sizeof f);
scanf("%d%d%d%d", &l1, &l2, &l3, &d);
printf("%lld\n", dfs(l1, l2, l3, d));
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: