P4996 咕咕咕

Posted garen-wang

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了P4996 咕咕咕相关的知识,希望对你有一定的参考价值。

贡献法+组合数学

讲道理一看到辣么小的(n),我就想到了状压dp。

枚举子集?哦,(O(3^n))的复杂度。但是我没有注意到(n=20)的时候是过不了的。

接下来我就在想70pts的状压dp要怎么写?

没有清楚定义状态的我连样例2都过不了,只能够手动枚举拿30pts。

所以最简单的月赛也爆炸了


70pts的状压

下面的做法是借鉴luogu题解的,不是抄袭。(你信吗?)

dp[i]表示从全0转移到i状态的所有歉意值之和。

那么会有

[dp[i]=sum{dp[j] + qy[j] imes num[j]}, j in i and j eq emptyset]

其中num[j]表示从全0转移到j的方案数,qy[j]表示当前这个状态的歉意值。

num[j]自然也是可以递推的,可以这么递推:

[num[j] = sum{num[k]}, k in j and k eq emptyset]

用枚举子集的优化技巧就可以做到(O(3^n))的搞出来了。

不给代码,题解里面是有的。

我的错误之处:没有意识到方案数是对答案有影响的。

满分做法

使用贡献法,那么每一个歉意值就会对答案产生贡献了。

产生的贡献是多少?是这个状态在所有方案中出现的次数 乘以 这个方案的歉意值。

还能够发现:其实一个状态只跟它的01个数有关,跟她们的顺序是无关的。

所以设一个(num[i])表示填(i)个1的方案数,那么就可以递推出来了。

递推式是这样子的:

[num[i] = sum_{j=1}^n{num[i-j] imes C_i^j}]

那么最后的答案就是该方案0的个数 乘以 该方案1的个数 乘以 这个方案的歉意值。

对了:注意取膜!否则你就只有80pts啦。

代码:

#include<cstdio>
#include<cstring>
#define ll long long
const int maxn = 21, maxN = 1048580;
const int MOD = 998244353;
ll dp[maxN];
ll qy[maxN];
ll num[maxn];
ll C[maxn][maxn];
int n, m;

void init()
{
    for(int i = 0; i <= 20; i++)
    {
        C[i][0] = C[i][i] = 1;
    }
    for(int i = 1; i <= 20; i++)
    {
        for(int j = 1; j < i; j++)
        {
            C[i][j] = (C[i - 1][j - 1] + C[i - 1][j]) % MOD;
        }
    }
}
int popcount(char *ch)
{
    int len = strlen(ch);
    int res = 0;
    for(int i = len - 1; i >= 0; i--)
    {
        if(ch[i] == ‘1‘) res++;
    }
    return res;
}
int main()
{
    init();
    scanf("%d%d", &n, &m);
    num[0] = 1;
    for(int i = 1; i <= n; i++)
    {
        for(int j = 1; j <= i; j++)
        {
            num[i] = (num[i] + C[i][i - j] * num[i - j] % MOD) % MOD;
        }
    }
    ll ans = 0;
    for(int i = 1; i <= m; i++)
    {
        char ch[25]; int x;
        scanf("%s%d", ch, &x);
        int temp = popcount(ch), len = strlen(ch);
        ans = (ans + x * num[temp] % MOD * num[len - temp] % MOD) % MOD;
    }
    printf("%lld
", ans);
    return 0;
}

以上是关于P4996 咕咕咕的主要内容,如果未能解决你的问题,请参考以下文章

2019雅礼集训 D7T3 convex [咕咕咕]

每日三题 Day5--leetcode9820250--咕咕咕

AtCoder ABC 163 题解(难题日常咕咕咕

2019雅礼集训 D8T1 union [咕咕咕]

雅礼集训D1T3 math [咕咕咕]

To Do List | 事实上是咕咕咕计划