bzoj4321 queue2 動態規劃

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

題意:給一個數,找出全部相鄰兩數大小不相鄰的排列數。ios

考慮一下,用$f[i][j][k]$表示當前已經插入$i$個數,出現了$j$對相鄰數字大小相鄰的狀況,$k==1$表示最後兩個數字大小相鄰,反之則不相鄰。數組

思考一個新的狀態如何由已知狀態轉移而來。ide

對於$f[i][j][0]$:spa

  • 能夠插在$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]$:code

  • 能夠插在$f[i-1][j][1]$的$(j-1)$和$(j-2)$之間,只有一種狀況;
  • 能夠插在$f[i-1][j-1][0/1]$的$(j-1)$旁邊,其中$0$有兩個位置可選,$1$只有一個位置可選(另外一個已被上一種狀況佔用了)

而後就正常寫就好了……注意開滾動數組壓內存……blog

 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\n",f[n&1][0][0]);
26 }
27 int sb=haha();
28 int main(){;}
bzoj4321
相關文章
相關標籤/搜索
本站公眾號
   歡迎關注本站公眾號,獲取更多信息