zoukankan      html  css  js  c++  java
  • SDOI 2010 地精部落 DP

    题目链接bzoj点我:-) 洛谷点我:-)

    题目描述
    给你n,p,请你求出满足这个条件的由1至n这n个数组成的排列有多少种,答案对p取模:即任意的连续上升或下降的一段数字区间长度不超过2(也称震荡序列)

    数据范围
    对于20%的数据,满足N≤10;
    对于40%的数据,满足N≤18;
    对于70%的数据,满足N≤550;
    对于100%的数据,满足3≤N≤4200,P≤109

    思路
    定义f[i][j][k]为取1i的数字,它们在最终序列中被分成j块,并且两头的块加新的大数字不合法的个数为k(0至2)
    转移方程:
    1.把原来两块的连起来:f[i+1][j1][k]+=f[i][j][k](j1)
    2.和其中一块连起来:f[i+1][j][k+1]+=f[i][j][k](2k)
    3.自己单独创块:f[i+1][j+1][k]+=f[i][j][k](j+1k)

    答案:f[n][1][0]+f[n][1][1]+f[n][1][2]
    再把数组滚一滚就可以了

    感想
    也是打算练基础的一道题,这么好的一道题,可惜我太菜了做不出来,网上大部分题解不是我这个东西,但是。。还是找个时间写写那等玄学方法好。这种DP,以前碰到过,那个浙江的波浪,还没打代码的,啊赶紧要写了。
    另外,这个方法很神奇啊,可能有人问那个我的数字在与任意一个块连接起来的时候,为啥只管两边的,你想想如果加在中间,肯定不合法啊是吧,我以后加的数越来越大了啊,这个数一边比它小一边比它大啊。。
    我觉得这种方法最最重要的,一是它的块的位置是灵活的,只有一个相对的位置,你不用管太多譬如它到底在原序列什么地方啊,你根本不用想这些,你想让它中间有多少空就有多少空,二是它加数字的时候是从小到大的,所以啊,很多神奇的性质就满足了,自己慢慢领会吧

    代码

    //miaomiao 2017.2.1
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<cmath>
    #include<iostream>
    #include<algorithm>
    
    using namespace std;
    
    #define LL long long
    #define Set(a, v) memset(a, v, sizeof(a))
    #define For(i, a, b) for(int i = (a); i <= (int)(b); i++)
    #define Forr(i, a, b) for(int i = (a); i >= (int)(b); i--)
    
    #define N (4200+5)
    
    LL f[2][N][3];
    
    int main(){
        int n, P;
        scanf("%d%d", &n, &P);
    
        int a = 1;
        f[1][1][0] = 1;
        For(i, 1, n-1){
            Set(f[a^1], 0);
            For(j, 1, min(i, n-i+1)) For(o, 0, 2)
                if(f[a][j][o]){
                    if(j > 1) f[a^1][j-1][o] = (f[a^1][j-1][o]+f[a][j][o]*(j-1)%P)%P;
                    if(o < 2) f[a^1][j][o+1] = (f[a^1][j][o+1]+f[a][j][o]*(2-o)%P)%P;
                    f[a^1][j+1][o] = (f[a^1][j+1][o]+f[a][j][o]*(j+1-o)%P)%P;
                }
            a^=1;
        }
        printf("%lld\n", (f[a][1][0]+f[a][1][1]+f[a][1][2])%P);
    
        return 0;
    }
    Miaomiao❤ ++RP
  • 相关阅读:
    单元测试
    python gdb
    圣诞树
    网络是怎样连接的 读书笔记
    POJ2104 K-th Number(整体二分)
    [SDOI2011]消耗战
    [HNOI2011]XOR和路径
    [HNOI2013]游走
    [JSOI2008]球形空间产生器
    POJ2728 Desert King
  • 原文地址:https://www.cnblogs.com/miaomiao1220/p/6642345.html
Copyright © 2011-2022 走看看