• [BZOJ1925][SDOI2010]地精部落


    做之前:什么鬼题目...

    做之后:一道妙极了的DP

    首先我们发现第一个数是山峰和第一个数是山谷的个数是一样的------①

    在一个波动数列中,若两个数字 i 与 i+1 不相邻,那么我们直接交换这两个数字就可以组成一个新的波动数列------②

    由①深入思考:把一个波动序列的每一项$a_{i}$变为n+1-$a_{i}$就会得到与当前序列波动性相反的一个数列------③

    比如:1 3 2----->3 1 2

    所以我们只用考虑一种情况,最后把ans*2

    假设dp[i][j]表示用前i个数组成的序列且第一个数是j

    由②有j与j+1不相邻时:dp[i][j]=dp[i][j-1]

    由③有j与j+1相邻是:dp[i][j]=dp[i-1][i-(j-1)];

    然后总数加起来即可

     1 #include<cstdio>
     2 #include<queue>
     3 #include<iostream>
     4 #include<cstring>
     5 using namespace std;
     6 inline int read(){
     7     int ans=0,f=1;char chr=getchar();
     8     while(!isdigit(chr)){if(chr=='-') f=-1;chr=getchar();}
     9     while(isdigit(chr)){ans=(ans<<3)+(ans<<1)+chr-48;chr=getchar();}
    10     return ans*f;
    11 }int n,ha,dp[2][4201],ans;
    12 int main(){
    13     n=read(),ha=read();
    14     dp[0][2]=1;
    15     for(int i=3;i<=n;i++)
    16         for(int j=2;j<=i;j++)
    17             dp[i&1][j]=(dp[i&1][j-1]+dp[(i-1)&1][i-j+1])%ha;
    18     for(int i=2;i<=n;i++) ans=(ans+dp[n&1][i])%ha;
    19     cout<<(ans<<1)%ha;
    20     return 0;
    21 }
  • 相关阅读:
    ASP.NET Core 进程内(InProcess)托管
    ASP.NET Core 中的 Main 方法
    ASP.NET Core Web 项目文件
    5)
    4)
    单词
    html5单词
    3)
    2)
    1)
  • 原文地址:https://www.cnblogs.com/zhenglw/p/10549310.html
Copyright © 2020-2023  润新知