• B4321 queue2 dp


    这个题的dp真的恶心。首先,一开始我以为是一道数论题,但是组合数和这个题没啥关系。dp方程巨麻烦,状态是dp[i][j][0/1],代表i位连了j个,上一位是否连着。然后开始转移,证明如下:

    我们先来分析i-1,i相邻,也就是f[i][j][1]怎么推。
    对于i,i-1,i-2,有这几种关系,
    本来i-1与i-2相邻,将i插入两者中,拆了一对(i-1,i-2),又形成了一对(i-1,i),这样方案来源于f[i-1][j][1]。
    本来i-1与i-2相邻,将i插入与i-1相邻却不被i-1与i-2夹着,多形成了一对(i-1,i),这样方案来源于f[i-1][j-1][1]。
    本来i-1与i-2不相邻,将i插入与i-1相邻,形成了一对(i-1,i),这样方案来源于f[i-1][j-1][1],由于i-1的左右够可以插,方案就乘2。
    这样f[i][j][1]=f[i1][j1][1]+f[i1][j][1]+f[i1][j1][0]2


    关于i-1,i不相邻,也就是f[i][j][0]怎么推
    本来i-1与i-2相邻,将i插入j对相邻的数的任意一对,这样就破坏了一对,这样方案来源于f[i-1][j+1][1],有(j+1-1)种位置可以选(i-1与i-2那对不能拆,因为插入又会形成新的)。
    本来i-1与i-2不相邻,将i插入j对相邻的数的任意一对,这样就破坏了一对,这样方案来源于f[i-1][j+1][0],有(j+1)种位置可以选。
    又可能i不去拆开相邻的数,就可以来源于
    f[i-1][j][1]*(i-j-1)(可以插入i-1与i-2,不改变对数) 或 f[i-1][j][0]*(i-j-2)
    综合

    f[i][j][0]=f[i1][j+1][1]j+f[i1][j+1][0](j+1)+f[i1][j][1](ij1)+f[i1][j][0](ij2)

    很难推的题呀。。。。

    题干:

    Description
    n 个沙茶,被编号 1~n。排完队之后,每个沙茶希望,自己的相邻的两
    人只要无一个人的编号和自己的编号相差为 1(+1 或-1)就行; 
    现在想知道,存在多少方案满足沙茶们如此不苛刻的条件。 
    
    Input
    只有一行且为用空格隔开的一个正整数 N,其中 100%的数据满足 1≤N ≤ 1000; 
    
    Output
    一个非负整数,表示方案数对 7777777 取模。   
    
    Sample Input
    4               
    Sample Output
    2 
    
    样例解释:有两种方案 2 4 1 33 1 4 2 
    HINT
    
    Source

    代码:

    #include<iostream>
    #include<cstdio>
    #include<cmath>
    #include<queue>
    #include<algorithm>
    #include<cstring>
    using namespace std;
    #define duke(i,a,n) for(int i = a;i <= n;i++)
    #define lv(i,a,n) for(int i = a;i >= n;i--)
    #define clean(a) memset(a,0,sizeof(a))
    const int INF = 1 << 30;
    const int mod = 7777777;
    typedef long long ll;
    typedef double db;
    template <class T>
    void read(T &x)
    {
        char c;
        bool op = 0;
        while(c = getchar(), c < '0' || c > '9')
            if(c == '-') op = 1;
        x = c - '0';
        while(c = getchar(), c >= '0' && c <= '9')
            x = x * 10 + c - '0';
        if(op) x = -x;
    }
    template <class T>
    void write(T x)
    {
        if(x < 0) putchar('-'), x = -x;
        if(x >= 10) write(x / 10);
        putchar('0' + x % 10);
    }
    ll dp[1010][1010][3];
    int main()
    {
        int n;
        read(n);
        dp[1][0][0] = 1;
        duke(i,2,n)
        {
            duke(j,0,i)
            {
                dp[i][j][1] = (dp[i - 1][j - 1][1] + dp[i - 1][j][1] + dp[i - 1][j - 1][0] * 2) % mod;
                dp[i][j][0] = (dp[i - 1][j][0] * (i - j - 2) + dp[i - 1][j + 1][1] * j + dp[i - 1][j + 1][0] * (j + 1) + dp[i - 1][j][1] * (i - j - 1)) % mod;
            }
        }
        printf("%lld
    ",dp[n][0][0]);
        return 0;
    }
  • 相关阅读:
    HDU 3085 Nightmare Ⅱ[双向广搜]
    HDU 4028 The time of a day [离散化DP]
    HDU4027 Can you answer these queries? [线段树]
    HDU 4331 Image Recognition [边上全为1构成的正方形个数]
    HDU4026 Unlock the Cell Phone [状态压缩DP]
    HDU 4333 Revolving Digits [扩展KMP]
    HDU4335 What is N? [数论(欧拉函数)]
    工程与管理
    项目管理笔记一
    通过100个单词掌握英语语法(七)ask
  • 原文地址:https://www.cnblogs.com/DukeLv/p/9535798.html
Copyright © 2020-2023  润新知