[SCOI2008]着色方案

13 篇文章 0 订阅

希望我明天四级稳过…(所以我为什么还在刷题)
这里
题解:题目给的数据范围并不算大,所以我们可以有两个方案,爆搜或者dp,但爆搜不仅不好搜而且肯定会超时,所以我们只好用dp来解决这个问题。

我本来想给每种颜色设一个状态,然后来dp,但5的15次方很明显是超时的,而且也会爆空间。所以我们可以换一种思路,我们看到每种颜色最多只有五个,所以我们可以用五维来表示只能涂n(n>=1&&n<=5)个的木块的油漆各有多少种,再开一维来表示当前选择的是那一维,这样我们就可以用记忆化搜索来解决题目了。

我们需要注意,假设当前我选择了只能涂三个木块的油漆,能涂两块的肯定会多一种,能涂三块的会少一种,但我们下次如果选择能涂两块的是要少一个选择的(因为有一个是从上个三转移过来的,如果再远它颜色会相同)。这样我们就很容易解决这个问题了。

还有不懂得看代码= =

#include<bits/stdc++.h>
#define ll long long
#define pr pair<ll,ll>
#define ios ios::sync_with_stdio(false)
#define CRL(a) memset(a,0,sizeof a)
#define endl "\n"

using namespace std;
const int mod = 1e9 + 7;

int dp[16][16][16][16][16][6];
int t[10];
ll dfs(int a,int b,int c,int d,int e,int last)
{
    if(dp[a][b][c][d][e][last])
        return dp[a][b][c][d][e][last];
    if(a+b+c+d+e==0)
        return 1;
    ll ans = 0;
    if(a)
        ans += (a - (last == 2)) * dfs(a - 1, b, c, d, e, 1);
    if(b)
        ans += (b - (last == 3)) * dfs(a + 1, b - 1, c, d, e, 2);
    if(c)
        ans += (c - (last == 4)) * dfs(a, b + 1, c - 1, d, e, 3);
    if(d)
        ans += (d - (last == 5)) * dfs(a, b, c + 1, d - 1, e, 4);
    if(e)
        ans += (e - 0) * dfs(a, b, c, d + 1, e - 1, 5);
    dp[a][b][c][d][e][last] = ans % mod;
    return dp[a][b][c][d][e][last];
}
int main()
{
    int n;
    cin >> n;
    for (int i = 1; i <= n;i++)
    {
        int a;
        cin >> a;
        t[a]++;
    }
    cout << dfs(t[1], t[2], t[3], t[4], t[5], 0);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值