• [BZOJ 1794] Linear Garden


    Link:

    BZOJ 1794 传送门

    Solution:

    IOI2008官方题解:传送门

    要求序号,其实就是算字典序比其小的序列个数

    从而使用数位$dp$的思想来解题,关键在于维护序列要$balance$这个条件

    可以将$P$看作$-1$,而将$L$看作$+1$,最终要保证整个序列在一个宽最多为2的横条内

    接下来就可以用状压$dp$计算方案数了

    但实际上由于只有两种状态,每一种情形下是能直接推出结论的:

    1、如果在宽仅为1的横条内,贡献为$2^{floor(k)}+2^{ceil(k)-1}$

    2、如果在宽为2的横条内,贡献为$2^{floor(t)}$

    官方题解好像情况2的结论有错?

    状压$dp$的神仙做法:传送门 ,有点没看懂正确性在哪里……

    Code:

    #include <bits/stdc++.h>
    
    using namespace std;
    const int MAXN=1e6+10;
    char s[MAXN];
    int n,m,mx,mn,cur,l,pre[MAXN],res; 
    
    int main()
    {
        scanf("%d%d%s",&n,&m,s);l=strlen(s);
        pre[0]=1;for(int i=1;i<=1e6;i++) pre[i]=pre[i-1]*2%m;
        for(int i=0;i<l;i++)
        {
            if(s[i]=='P')
            {
                if(max(mx,cur+1)-mn<=2) 
                {
                    float t=(l-i-(float)1)/2;
                    if(max(mx,cur+1)-mn==1)
                        (res+=pre[(int)floor(t)]+pre[(int)ceil(t)]-1+m)%=m;
                    else (res+=pre[(int)floor(t)])%=m;
                }
                cur--;mn=min(mn,cur);
            }
            else cur++,mx=max(mx,cur);
        }
        printf("%d",(res+1)%m);
        return 0;
    }

    Review:

    1、对于按字典序排列计数问题,都可以引申为数位$dp$的题目

    2、每一位状态数较小时尝试推结论

    注意数形结合

  • 相关阅读:
    存储引擎的优缺点及增删改查基本操作
    安装Mariadb
    Mysql 入门概念
    Nginx语法着色
    find用法,文件压缩和lsof和cpio
    软件包管理
    Django 生成六位随机图片验证码
    Django自定义过滤器和自定义标签
    Django零碎知识点
    jQuery实现淡入淡出样式轮播
  • 原文地址:https://www.cnblogs.com/newera/p/9247725.html
Copyright © 2020-2023  润新知