• 火题大战Vol.0 B 计数DP


    火题大战Vol.0 B

    题目描述

    (n) 个沙茶,被编号 (1)~$ n$。排完队之后,每个沙茶希望,自己的相邻的两人只要无一个人的编号和自己的编号相差为 (1)(+1)(-1))就行;

    现在想知道,存在多少方案满足沙茶们如此不苛刻的条件。

    输入格式

    只有一行且为用空格隔开的一个正整数 (N)

    输出格式

    一个非负整数,表示方案数对 (7777777) 取模。

    样例

    样例输入

    4

    样例输出

    2

    样例解释

    有两种方案 (2 4 1 3)(3 1 4 2)

    数据范围与提示

    对于(30\%)的数据满足(N leq 20)

    对于(100\%)的数据满足(1 leq N leq 1000) ;

    分析

    我们设 (f[i][j][0]) 为填了 (1)(i),当前有 (j) 对两两之间相差一的人,并且(i)(i-1)不相邻的方案数

    (f[i][j][1]) 为填了 (1)(i),当前有 (j) 对两两之间相差一的人,并且(i)(i-1)相邻的方案数

    对于(f[i][j][0]),如果我们在这(j)对人的中间插入一个数,那么两两之间相差一的人会少一对,因为此时(i)(i-1)不相邻

    转移方程 (f[i+1][j-1][0]+=j imes f[i][j][0])

    如果我们在(i)的旁边插入(i+1),那么两两之间相差一的人会多一对,并且(i)(i+1)相邻,因此会转移至 (f[i+1][j+1][1])

    转移方程 (f[i+1][j+1][1]+=2 imes f[i][j][0])

    此时,我们在剩下的位置插入不会对对数产生影响,即

    (f[i+1][j][0]+=(i-1-j) imes f[i][j][0])

    对于(f[i][j][1]) 如果我们在(i)(i-1)的中间插入(i+1),则有

    (f[i+1][j][1]+=f[i][j][1])

    如果我们在(i)的另一边插入(i+1),则有

    (f[i+1][j+1][1]+=f[i][j][1];)

    如果我们在其它的 (j-1) 个空位中插入,则有

    (f[i+1][j-1][0]+=f[i][j][1]*(j-1))

    如果我们在其它的空位中插入,则有

    (f[i+1][j][0]+=f[i][j][1]*(i-j))

    代码

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn=1e3+5;
    #define int long long
    int f[maxn][maxn][3];
    const int mod=7777777;
    signed main(){
    	int n;
    	scanf("%lld",&n);
    	f[2][1][1]=2;
    	for(int i=1;i<=n;i++){
    		for(int j=0;j<i;j++){
    			f[i+1][j-1][0]+=j*f[i][j][0];
    			f[i+1][j-1][0]%=mod;
    			f[i+1][j+1][1]+=2*f[i][j][0];
    			f[i+1][j+1][1]%=mod;
    			if(i-j-1>0){
    				f[i+1][j][0]+=(i-1-j)*f[i][j][0];
    				f[i+1][j][0]%=mod;
    			}
    			if(j-1>0) {
    				f[i+1][j-1][0]+=f[i][j][1]*(j-1);
    				f[i+1][j-1][0]%=mod;
    			}
    			f[i+1][j][1]+=f[i][j][1];
    			f[i+1][j][1]%=mod;
    			f[i+1][j+1][1]+=f[i][j][1];
    			f[i+1][j+1][1]%=mod;
    			f[i+1][j][0]+=f[i][j][1]*(i-j);
    			f[i+1][j][0]%=mod;
    		}
    	}
    	printf("%lld
    ",f[n][0][0]);
    	return 0;
    }
    
  • 相关阅读:
    王钿《淡逻辑设计的学习》
    格雷码
    perl中 数组 和 列表的区别!
    FPGA建立时间(setup time)&保持时间(hold time)&竞争和冒险&毛刺
    Verilog三段式状态机描述
    [转]Unit Testing 101: Are You Testing Your JavaScript?
    [JavaScript]Jasmine中如何选择只运行部分Cases
    Java编程中推荐的Singleton模式
    [转]如何在Intellij中使用JsTestDriver做Javascript的Unit Testing
    [Groovy]Test with Spock
  • 原文地址:https://www.cnblogs.com/liuchanglc/p/13527104.html
Copyright © 2020-2023  润新知