bzoj4321: queue2(DP)

  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
",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
",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
",f[n]);
    return 0;
}
View Code
原文地址:https://www.cnblogs.com/Sakits/p/7466014.html