zoukankan      html  css  js  c++  java
  • BZOJ 1925地精部落题解

    题目链接

    一道神仙题,有很多思考的方式,这里选择最好理解的一种来讲

    我们将序列分为两种,一种开头递增,一种开头递减,显然这两种序列的数目是一样的

    现在我们只用考虑开头递增的情况

    f[i][j]表示前i个数,最后一个数字在前i个数的排名在1~j之间的方案数

    显然有f[i][j]=f[i][j-1],如果最后一个数下降f[i][j]可以由f[i-1][i-j]转移过来,

    如果最后一个数上升,则可以由f[i-1][j-1]转移过来,考虑到每一次转移时没有考虑之前一次的状态最后是上升还是下降的

    我们都转移过来会错,由于波动序列具有对称性且我们只考虑了开头递增的序列,所以我们只用从f[i-1][i-j]来转移就ok了

    还有,记得加上滚动数组进行优化

    # include<iostream>
    # include<cstring>
    # include<algorithm>
    # include<cmath>
    # include<cstdio>
    using namespace std;
    const int mn = 4205;
    long long f[2][mn];
    int n,p;
    int main()
    {
        scanf("%d%d",&n,&p);
        f[0][1]=1;
        if(n==1)
        {
            printf("1");
            return 0;
        }
        int cnt=0;
        for(int i=2;i<=n;i++)
        {
            cnt=1-cnt;
            for(int j=1;j<=i;j++)
                f[cnt][j]=(f[cnt][j-1]+f[1-cnt][i-j])%p;
        }
        printf("%lld",(f[cnt][n]*2)%p);
        return 0;
    }
  • 相关阅读:
    DNS部署与安全
    DHCP部署与安全
    jenkins漏洞复现
    Apache Axis2 漏洞复现
    制作war包
    JBOOS 漏洞复现
    Tomcat漏洞复现
    编写登陆接口(2)
    学习使用新工具Pycharm
    while练习99乘法表
  • 原文地址:https://www.cnblogs.com/logeadd/p/9710049.html
Copyright © 2011-2022 走看看