首页 > 其他分享 >DP 与计数

DP 与计数

时间:2023-11-08 22:14:47浏览次数:32  
标签:ifac int ret 计数 DP fac dp 255

NFLSOJ

A

CF294C Shaass and Light
考虑初始已点亮的灯将所有剩下的灯划分成的连续段。除开头结尾外,每个长为 \(l\) 的连续段有 \(2 ^ l\) 种操作序列。开头结尾的连续段只有 \(1\) 种操作序列。从前往后将所有的操作序列归并到全局的操作序列里,拿组合数随便乱搞搞就好了。

代码
#include <iostream>
#include <algorithm>
#define int long long
using namespace std;
const int P = 1e9 + 7;
int n, m;
int a[1005];
inline int qpow(int x, int y) {
    if (y <= 0) 
        return 1;
    int ret = 1;
    while (y) {
        if (y & 1) 
            ret = ret * x % P;
        y >>= 1;
        x = x * x % P;
    }
    return ret;
}
int inv[1005], ifac[1005], fac[1005];
inline int C(int n, int m) { return (n < m ? 0 : fac[n] * ifac[m] % P * ifac[n - m] % P); }
signed main() {
    cin >> n >> m;
    inv[0] = ifac[0] = fac[0] = inv[1] = ifac[1] = fac[1] = 1;
    for (int i = 2; i <= n; i++) {
        inv[i] = (P - P / i) * inv[P % i] % P;
        fac[i] = fac[i - 1] * i % P;
        ifac[i] = ifac[i - 1] * inv[i] % P;
    }
    for (int i = 1; i <= m; i++) cin >> a[i];
    sort(a + 1, a + m + 1);
    int res = n - m;
    int ans = C(res, a[1] - 1);
    res -= (a[1] - 1);
    ans = ans * C(res, n - a[m]) % P;
    res -= (n - a[m]);
    for (int i = 2; i <= m; i++) {
        ans = ans * qpow(2, a[i] - a[i - 1] - 2) % P;
        ans = ans * C(res, a[i] - a[i - 1] - 1) % P;
        res -= (a[i] - a[i - 1] - 1);
    }
    cout << ans;
    return 0;
}

B

CF1753C Wish I Knew How to Sort
发现最终序列一定是前面全是 \(0\),后面全是 \(1\)。设有 \(k\) 个 \(0\),则我们判断是否排好序的标准就是前 \(k\) 个数里是否有 \(k\) 个 \(0\)。又发现操作后任意一段前缀里 \(0\) 的个数是单调不降的。于是可以设计出 dp 状态:\(dp[i]\) 表示前 \(k\) 个数里有 \(i\) 个 \(0\) 时的期望步数。最终答案即为 \(dp[k]\)。转移考虑期望经过多少步可以使得前 \(k\) 个数里的 \(0\) 增加。设当前前 \(k\) 个里共有 \(i\) 个 \(0\),则要增加就必须选到前面的 \(1\) 和后面的 \(0\)。可以发现前面 \(1\) 的个数和后面 \(0\) 的个数都是 \(k - i\) 个。而总的选择方案共有 \(\binom{n}{2}\) 种。所以此时一次操作给前 \(k\) 个增加一个 \(0\) 的概率即为 \(\frac{(k - i) ^ 2}{\binom{n}{2}}\),期望次数即为 \(\frac{\binom{n}{2}}{(k - i) ^ 2}\)。于是有 \(dp[i + 1] = dp[i] + \frac{\binom{n}{2}}{(k - i) ^ 2}\)。直接算即可。

代码
#include <iostream>
#define int long long
using namespace std;
const int P = 998244353;
inline int qpow(int x, int y) {
    int ret = 1;
    while (y) {
        if (y & 1) 
            ret = ret * x % P;
        y >>= 1;
        x = x * x % P;
    }
    return ret;
}
int dp[200005];
int a[200005];
signed main() {
    int tc;
    cin >> tc;
    while (tc--) {
        int n, k = 0;
        cin >> n;
        for (int i = 1; i <= n; i++) cin >> a[i], a[i] ^= 1, k += a[i];
        for (int i = 1; i <= n; i++) a[i] += a[i - 1];
        dp[a[k]] = 0;
        int S = n * (n - 1) / 2;
        for (int i = a[k] + 1; i <= k; i++) dp[i] = (dp[i - 1] + S % P * qpow((k - i + 1) * (k - i + 1), P - 2) % P) % P;
        cout << dp[k] << "\n";
    }
    return 0;
}

C

CF1657E Star MST
题目限制等价于以 \(1\) 为中心的菊花是图的一棵 MST。也就是每个点到 \(1\) 的边权必须小于等于到其他点的边权,不然换成那条更小的边肯定可以使得 MST 的权值变小。于是可以考虑 dp。我们从小到大给每条与 \(1\) 相连的点赋权,定义 \(dp[i][j]:\) 已经给 \(i\) 个点的与 \(1\) 相连的边赋了权,最后一次赋权赋的是 \(j\) 的方案数。考虑转移。对于一个 \(dp[i][j]\),我们枚举给几个点(边)赋上 \(j\) 的权,记为 \(m\)。然后再枚举上次赋的是什么权,记为 \(x\)。再记 \(t = i - m\),则 \(dp[i][j]\) 可以从 \(dp[t][x]\) 转移。考虑转移系数。显然我们要先在剩下的 \(n - t\) 个点里选出 \(i - t\) 个赋权。然后要在这选出的 \(i - t\) 个点里相互连边,还要向前面的 \(t - 1\) 个点连边(减 \(1\) 是因为不用考虑向 \(1\) 连)。新连的边的权值必然是要大于等于 \(j\) 的(因为其有一个端点向 \(1\) 连了权为 \(j\) 的边),于是每条边有 \(k - j + 1\) 种选权值的方案。总共是 \(\binom{n - t}{i - t}(k - j + 1)^{(\frac{(i - t)(i - t - 1)}{2} + (i - t)(t - 1))}\),这就是转移系数。上面那个指数可以化简变成 \(\frac{(i - t)(i + t - 3)}{2}\),于是转移:\(dp[i][j] = \sum\limits_{t = 1}^{i - 1}(\sum\limits_{x = 0}^{k})\binom{n - t}{i - t}(k - j + 1)^{\frac{(i - t)(i + t - 3)}{2}}\)。使用前缀和优化即可做到 \(O(n^3)\)。

代码
#include <iostream>
#define int long long
using namespace std;
const int P = 998244353;
int f[255][255];
int g[255][255];
int inv[255], ifac[255], fac[255];
inline void Cpre(int n) {
    inv[0] = ifac[0] = fac[0] = inv[1] = ifac[1] = fac[1] = 1;
    for (int i = 2; i <= n; i++) {
        inv[i] = (P - P / i) * inv[P % i] % P;
        fac[i] = fac[i - 1] * i % P;
        ifac[i] = ifac[i - 1] * inv[i] % P;
    }
}
inline int C(int n, int m) { return n < m || n < 0 || m < 0 ? 0 : fac[n] * ifac[m] % P * ifac[n - m] % P; }
inline int qpow(int x, int y) {
    int ret = 1;
    while (y) {
        if (y & 1) 
            ret = ret * x % P;
        y >>= 1;
        x = x * x % P;
    }
    return ret;
}
signed main() {
    int n, K;
    cin >> n >> K;
    Cpre(max(n, K));
    f[1][0] = 1;
    for (int i = 0; i <= K; i++) g[1][i] = 1;
    for (int i = 2; i <= n; i++) {
        for (int j = 1; j <= K; j++) {
            for (int t = 1; t < i; t++) 
                f[i][j] = (f[i][j] + g[t][j - 1] * C(n - t, i - t) % P * qpow(K - j + 1, (i - t) * (i + t - 3) / 2) % P) % P;
            g[i][j] = (g[i][j - 1] + f[i][j]) % P;
        }
    }
    cout << g[n][K];
    return 0;
}

D

标签:ifac,int,ret,计数,DP,fac,dp,255
From: https://www.cnblogs.com/forgotmyhandle/p/17818447.html

相关文章

  • 20231108数数与dp题笔记
    数数与dpCF294CShaassandLights记被分成的\(m+1\)段每一段的长度为\(l_i\)答案为\[\frac{(n-m)!}{\prod\limits_{i=1}^{m+1}l_i!}\times\prod\limits_{i=1}^{m+1}2^{l_i-1}\]前面是不同段之间的顺序打乱,后面是每一段中前\(l_i-1\)个操作各有\(2\)个选择CF1753CW......
  • .NET 8 IEndpointRouteBuilder详解
    Map​ 经过对WebApplication的初步剖析,我们已经大致对Web应用的骨架有了一定了解,现在我们来看一下HelloWorld案例中仅剩的一条代码:app.MapGet("/",()=>"HelloWorld!");//3添加路由处理​ 老规矩,看签名:publicstaticRouteHandlerBuilderMapGet(thisIEndpointRout......
  • MySql按周,按月,按日分组统计数据
    知识关键词:DATE_FORMAT<!--按日查询-->SELECTDATE_FORMAT(created_date,'%Y-%m-%d')astime,sum(money)moneyFROMo_finance_detailwhereorg_id=1000GROUPBYtime<!--按月查询-->SELECTDATE_FORMAT(created_date,'%Y-%m')astime,su......
  • 动态加载资源 释放时要注意 引入引用计数统计
    今天开发时,释放了预制体资源引起报错,这里直接使用了bundle.release因为预制体的精灵图片是动态加载的,释放时将精灵图片一并释放了,引起错误改为引用计数,解决问题 cocos资源释放文档:https://docs.cocos.com/creator/manual/zh/asset/release-manager.html  资源的动态引......
  • 汇编-当前位置计数器$
    符号$被称为当前位置计数器.dataselfPtrDWORD$;声明了一个变量selfPtr,并将其初始化为该变量的偏移量       ......
  • SP15637 GNYR04H - Mr Youngs Picture Permutations(线性 dp)
    题目求方案数,考虑dp——状态设计和边界——题目告诉了一个很显然的性质:每一排从左至右保证高度单调递减每一列从后往前保证高度单调递减那么可以发现,对于每一行,每一列,一定是按高度顺序插入,并且是连续插入,因为如果不连续,就无法保证单调递减的性质同时,它给出了另一个性......
  • ASP.NET性能计数器
       ASP.NET支持两组性能计数器:系统和应用程序。前者在ASP.NET性能计数器对象中的PerfMon中公开;后者在ASP.NETApplications性能对象中公开。ASP.NET性能对象中的StateServerSessions计数器(仅适用于在其中运行状态服务器的服务器计算机)和ASP.NETApplications性能......
  • 如何选择 Web 服务器性能计数器
    有数百个您可以从中选择要监视服务器活动的计数器。下面的列表描述了可用于监视您的Web服务器上负载,并为每个提供理想的值的计数器。收起该表格展开该表格对象或计数器理想的值内存每秒页0到20(如果通过80,表示问题)内存可用的字节数至少4兆字节(MB)内存提交的字节数不会......
  • P2196-DP【黄】
    清醒了一点后我又写了一道黄色DP题,做出来了,还行,开心不少了...中途暴露出一些问题1、深搜过程中既然用了二维数组,那么深搜时就应该用二维循环取最优解,而不是只从最后一行中进行一维循环取最优解。2、dfs递归的过程中应该用dfs!!!不应该像个智障一样的忘了用dfs,直接用dp数组忘了递归......
  • 国产MIPI转eDP方案|低成本替代LT6911方案|CS5523规格书
    ASLCS5523是MIPI DSI输入、DP/eDP输出转换芯片。MIPIDSI最多支持4个通道,每个通道的最大运行速度为1.5Gps。对于DP1.2输出,它由4个数据通道组成,支持1.62Gbps和2.7Gbps的链路速率。支持1.62Gbps和2.7Gbps的链路速率。它支持2560的最高分辨率*1440@60Hz.它只能使用单个1.8V电源,以......