1. 程式人生 > >bzoj4321: queue2(DP)

bzoj4321: queue2(DP)

urn pan std ring algo () display 中間 pla

  woc萬能的OEIS大法!這題居然是有遞推式的QAQ

  http://oeis.org/A002464

  這題的狀態想不出來T^T...

  f[i][j][0/1]表示前i個編號,有j對相鄰的編號位置上相鄰,i和i-1是否相鄰

  先考慮f[i][j][1]怎麽轉移。

  i和i-1相鄰,如果i-1和i-2相鄰的話,可以選擇把i插入這兩個中間,這樣相鄰的對數不會增加,所以可以從f[i-1][j][1]轉移。也可以不插入這兩個數之間,而是放在i旁邊,這樣相鄰對數會+1,所以可以從f[i-1][j-1][1]轉移。如果i-1和i-2不相鄰,可以放在i-1的左右兩邊,f[i][j][1]+=2*f[i-1][j-1][0]轉移。

  再考慮f[i][j][0]怎麽轉移。

  i不和i-1相鄰,可以去插入兩個相鄰數的中間,這樣相鄰對數-1,f[i][j][0]+=f[i-1][j+1][1]*j+f[i-1][j+1][0]*(j+1)。也可以不插入兩個相鄰數的中間,f[i][j][0]+=f[i-1][j][1]*(i-j-1)+f[i-1][j][0]*(i-j-2)。

  f[i][j][1]=f[i-1][j][1]+f[i-1][j][1]+f[i-1][j-1][0]*2

  f[i][j][0]=f[i-1][j+1][1]*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)

技術分享
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio> 
#include<algorithm>
#define ll long long 
using namespace std;
const int maxn=1010,mod=7777777;
int n,f[2][maxn][2];
int MOD(int x){return x>=mod?x-mod:x;}
int main()
{
    scanf(
"%d",&n);f[1][0][0]=1; for(int i=2;i<=n;i++) for(int j=0;j<i;j++) { f[i&1][j][1]=MOD(f[(i&1)^1][j][1]+(j>0?f[(i&1)^1][j-1][1]:0)); f[i&1][j][1]=MOD(f[i&1][j][1]+(j>0?MOD(f[(i&1)^1][j-1][0]<<1):0)); f[i&1][j][0]=MOD(1ll*f[(i&1)^1][j+1][1]*j%mod+1ll*f[(i&1)^1][j+1][0]*(j+1)%mod); f[i&1][j][0]=MOD(f[i&1][j][0]+MOD(1ll*f[(i&1)^1][j][1]*(i-j-1)%mod+1ll*f[(i&1)^1][j][0]*(i-j-2)%mod)); } printf("%d\n",f[n&1][0][0]); return 0; }
View Code

公式遞推:

技術分享
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio> 
#include<algorithm>
#define ll long long 
using namespace std;
const int maxn=1010,mod=7777777;
int n,f[maxn];
void read(int &k)
{
    int f=1;k=0;char c=getchar();
    while(c<0||c>9)c==-&&(f=-1),c=getchar();
    while(c<=9&&c>=0)k=k*10+c-0,c=getchar();
    k*=f;
}
int MOD(int x){return x>=mod?x-mod:x;}
int main()
{
    read(n);
    f[1]=1;f[2]=0;f[3]=0;f[4]=2;
    if(n<=4)return printf("%d\n",f[n]),0;
    for(int i=5;i<=n;i++)
    {
        f[i]=MOD(1ll*(i+1)*f[i-1]%mod-1ll*(i-2)*f[i-2]%mod+mod);
        f[i]=MOD(f[i]-1ll*(i-5)*f[i-3]%mod+mod);
        f[i]=MOD(f[i]+1ll*(i-3)*f[i-4]%mod);
    }
    printf("%d\n",f[n]);
    return 0;
}
View Code

bzoj4321: queue2(DP)