zoukankan      html  css  js  c++  java
  • bzoj4321 queue2 动态规划

    链接:http://www.lydsy.com/JudgeOnline/problem.php?id=4321

    题意:给一个数,找出所有相邻两数大小不相邻的排列数。

    考虑一下,用$f[i][j][k]$表示当前已经插入$i$个数,出现了$j$对相邻数字大小相邻的情况,$k==1$表示最后两个数字大小相邻,反之则不相邻。

    思考一个新的状态如何由已知状态转移而来。

    对于$f[i][j][0]$:

    • 可以插在$f[i-1][j+1][1]$的另外$j$对其中一对中间,共有$j$种情况;
    • 可以插在$f[i-1][j+1][0]$的其中一对中间,有$(j+1)$个位置可选;
    • 可以插在$f[i-1][j][1]$的其他位置,有$(i-j+1)$种情况;
    • 可以插在$f[i-1][j][0]$的其他位置,有$(i-j+2)$种情况。

    对于$f[i][j][i]$:

    • 可以插在$f[i-1][j][1]$的$(j-1)$和$(j-2)$之间,只有一种情况;
    • 可以插在$f[i-1][j-1][0/1]$的$(j-1)$旁边,其中$0$有两个位置可选,$1$只有一个位置可选(另一个已被上一种情况占用了)

    然后就正常写就行了……注意开滚动数组压内存……

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <algorithm>
     5 using namespace std;
     6 const int maxn=1005,mod=7777777;
     7 long long f[2][maxn][2];int n;
     8 int haha()
     9 {
    10     scanf("%d",&n);f[1][0][0]=1;
    11     for(int i=2;i<=n;i++)
    12     {
    13         int now=i&1;
    14         for(int j=0;j<i;j++)
    15         {
    16             f[now][j][1]=f[now^1][j][1];
    17             if(j)f[now][j][1]=(f[now][j][1]+f[now^1][j-1][1]%mod)%mod;
    18             if(j)f[now][j][1]=(f[now][j][1]+f[now^1][j-1][0]*2%mod)%mod;
    19             f[now][j][0]=f[now^1][j+1][1]*j%mod;
    20             f[now][j][0]=(f[now][j][0]+f[now^1][j+1][0]*(j+1)%mod)%mod;
    21             f[now][j][0]=(f[now][j][0]+f[now^1][j][1]*(i-j-1)%mod)%mod;
    22             f[now][j][0]=(f[now][j][0]+f[now^1][j][0]*(i-j-2)%mod)%mod;
    23         }
    24     }
    25     printf("%lld
    ",f[n&1][0][0]);
    26 }
    27 int sb=haha();
    28 int main(){;}
    bzoj4321
  • 相关阅读:
    hdu 5366 简单递推
    hdu 5365 判断正方形
    hdu 3635 并查集
    hdu 4497 数论
    hdu5419 Victor and Toys
    hdu5426 Rikka with Game
    poj2074 Line of Sight
    hdu5425 Rikka with Tree II
    hdu5424 Rikka with Graph II
    poj1009 Edge Detection
  • 原文地址:https://www.cnblogs.com/Loser-of-Life/p/7780340.html
Copyright © 2011-2022 走看看