E. Phoenix and Computers

前言:写了四个小时,推出巨多种dp式子,推了半天发现基本性质给忘掉了,然后重新推才搞定。人傻了。万物皆可DP


时间复杂度n3的DP。

先上code

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
 
int n,mod;
long long dp[405][202][2],mu[405][405];
 
int main()
{
    
    
    cin >> n >> mod ;
    for(int l = 0 ; l <= n ; ++l)
        mu[l][0] = mu[0][l] = 1;
    for(int l = 1 ; l <= n ; ++l)
        for(int r = 1 ; r <= n ; ++r)
            mu[l][r] = (mu[l-1][r]+mu[l][r-1])%mod;
    dp[1][0][1] = 1;
    for(int len = 2 ; len <= n ; ++len)
        dp[len][0][1] = (2*dp[len-1][0][1])%mod;
    for(int len = 2 ; len <= n ; ++len){
    
    
        for(int num = 1 ; num <= len/2 ; ++num){
    
    /// 01,11
            for(int mid = num*2 ; mid < len ; ++mid){
    
    
                dp[len][num][1] = (dp[len][num][1]%mod + (((dp[mid][num][0]*dp[len-mid][0][1])%mod)*mu[mid-num][len-mid])%mod )%mod;
            }
            dp[len][num][0] = dp[len-1][num-1][1];
        }
    }
    long long ans = 0;
    for(int num = 0 ; num <= n/2 - (n%2==0) ; ++num){
    
    
        ans = (ans%mod + dp[n][num][1]%mod)%mod;
    }
    cout << ans << endl ;
    return 0;
}

E. Phoenix and Computers
  题目类型:动态规划、dp。
  解析:可以把需要手动的位置看成1,不需要手动的地方看成0,变成01串问题,方便处理。
  第1步:观察,长度为len的01串,最多可以有len/2-(len%2==0)个0,可以枚举0的数量
  第2步:长串可以由短串转移,枚举串的长度
  第3步:一个串中,连续的1的部分的开启有固定的顺序的,简单来说必定围着(在左或者右)已经确定的顺序添加新开启的电脑,否则会意外的出现0。设dp[len][num][1]为长度len,结尾为1,有num个0的串开启顺序的方式数。则dp[len][0][1] = dp[len-1][0][1]*2

  第4步:想转移就要把串以某种方式切块,因为连续的1有固定的方式数,可以以此把含有num个0的串,分成左边含有num个0,并且以0结尾右边是连续的1
dp[len][num][1] = sum(dp[mid][num][0]*dp[len-mid][1]*mu[mid][len-mid])

  第5步:解释一下dp方程mu[][],我们知道dp数组记录的是顺序数,而对于两种固定的顺序,我们要组合起来,需要知道组合后的顺序数。比如说
  a:1 2 3 4 5
  b:9 8 7 6 5
  我们必须按照 a和b数组的顺序取数,但是每次可以从a中取,也可以从b中取,合并之后:1 9 2 8 3 7 4 6 5 5就是一个正确的例子,我们需要知道这样取的总方式数。
  设mu[l][r]为a数组有l个元素,b数组有r个元素时合并后的新顺序数。则mu[l][r] = mu[l-1][r] + mu[l][r-1]。即a有6个数,b有4个数时,可以转移成(a5个,b4个)+(a6个,b3个)的状态。
  dp方程的含义就是(顺序数 * 顺序数 * 两种长度的组合顺序数

猜你喜欢

转载自blog.csdn.net/m0_45699242/article/details/116382627