Processing math: 0%

[CSP-S2019]Emiya 家今天的饭 题解

CSP-S2 2019 D2T1

很不错的一题DP,通过这道题学到了很多。

身为一个对DP一窍不通的蒟蒻,在考场上还挣扎了1h来推式子,居然还有几次几乎推出正解,然而最后还是只能打个32分的暴搜滚粗


题意分析

给出一个矩阵,要求每行只能选一个节点,每列选的节点不能超过所有选的节点的一半,不能不选,给出每个节点的选择方案数,求总方案数

思路分析

可以看出,维护每列已选的节点复杂度太大,不太可行;因此很容易想到,先不考虑每列不超过一半的这个限制,求出总方案数,然后再减去考虑这个限制后不合法的方案数。现在问题就变成,求任意列选的节点超过所有选的节点的一半的方案数之和。

显然,在一个方案中,只可能有一列的节点超过所有选的节点的一半。因此可以想到枚举这个超过限制的列,然后对于这个列进行DP求解。

具体实现

f_{i,j,k}表示前i行选j个节点,当前枚举到的列选k个节点的方案数。对于每个列,复杂度为O(n^3),总的复杂度为O(mn^3),可以得到84分的高分。

想得到满分还需要进一步优化。考虑将某两个状态合并。观察状态,实际上我们想知道的只是j,k的大小关系,对于具体的值并不关心,考虑将它们合并到一维。

考虑我们需要的限制条件k>\left \lfloor \frac{j}{2} \right \rfloor,变形一下可以得到2k+n-j>n。观察这个式子,可以发现,n-j就是这n行里没有选的行数。然后一个奇妙的想法就出来了,对于每个节点,选它时当做该列选了两次,而对于某一行不选时,当做所有列选了一次,最终要找的就是当前列被选超过n次的方案。这样就成功地优化掉了第二维。

给一下状态转移方程:

f[j][k]=(f[j][k]+f[j-1][k]*(cnt[j]-w[j][i]))%P;//不选当前列
f[j][k+1]=(f[j][k+1]+f[j-1][k])%P;//不选当前行
f[j][k+2]=(f[j][k+2]+f[j-1][k]*w[j][i])%P;//选当前行当前列对应的节点

注意取模时出现负数的情况,记得开long long。

复制代码
#include<iostream>
#include<cstdio>
#include<cstring>
#define ll long long
using namespace std;
const int N=200,M=3000,P=998244353;//FFT(雾
int n,m;
ll ans=1;
ll cnt[N],w[N][M],f[N][M];
int main()
{
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=m;j++)
            scanf("%lld",&w[i][j]),cnt[i]=(cnt[i]+w[i][j])%P;
        ans=(ans*(cnt[i]+1))%P;//计算全部答案
    }
    ans=(ans+P-1)%P;//减去全部不选的情况
    for(int i=1;i<=m;i++)
    {
        memset(f,0,sizeof(f));
        f[0][0]=1;//DP初值
        for(int j=1;j<=n;j++)
            for(int k=0;k<=2*(j-1);k++)
            {
                f[j][k]=(f[j][k]+f[j-1][k]*(cnt[j]-w[j][i]))%P;
                f[j][k+1]=(f[j][k+1]+f[j-1][k])%P;
                f[j][k+2]=(f[j][k+2]+f[j-1][k]*w[j][i])%P;
            }
        for(int j=n+1;j<=2*n;j++)
            ans=(ans+P-f[n][j])%P;//减去当前枚举到的不合法方案
    }
    printf("%lld",ans);
    return 0;
}
复制代码
posted on   TEoS  阅读(1719)  评论(2编辑  收藏  举报
编辑推荐:
· 智能桌面机器人:用.NET IoT库控制舵机并多方法播放表情
· Linux glibc自带哈希表的用例及性能测试
· 深入理解 Mybatis 分库分表执行原理
· 如何打造一个高并发系统?
· .NET Core GC压缩(compact_phase)底层原理浅谈
阅读排行:
· 手把手教你在本地部署DeepSeek R1,搭建web-ui ,建议收藏!
· 新年开篇:在本地部署DeepSeek大模型实现联网增强的AI应用
· Janus Pro:DeepSeek 开源革新,多模态 AI 的未来
· 互联网不景气了那就玩玩嵌入式吧,用纯.NET开发并制作一个智能桌面机器人(三):用.NET IoT库
· 【非技术】说说2024年我都干了些啥
< 2025年1月 >
29 30 31 1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31 1
2 3 4 5 6 7 8

点击右上角即可分享
微信分享提示