zoukankan      html  css  js  c++  java
  • [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、每一位状态数较小时尝试推结论

    注意数形结合

  • 相关阅读:
    爬虫练习
    爬取豆瓣电影top250
    简单爬虫
    正则提取子域名和ip
    用户体验培训总结
    测试经验总结
    项目管理知识总结
    读书笔记——《留住好员工:爱他们,还是失去他们?》
    ISTQB学习笔记
    数据结构和算法with Python
  • 原文地址:https://www.cnblogs.com/newera/p/9247725.html
Copyright © 2011-2022 走看看