首页 > 其他分享 >预设型DP

预设型DP

时间:2024-07-20 12:08:40浏览次数:11  
标签:样例 贡献 预设 计数 两边 断点 DP

DP搬运工1

Description

给你 n,k,求有多少个 1 到 n 的排列,满足相邻两个数的 max 的和不超过 k。

Input Format

一行两个整数 n,k。

Output Format

一行一个整数 ansans 表示答案 \(\text{mod 998244353}\)。

Sample

样例输入1
4 10
样例输出1
16
样例输入2
10 66
样例输出2
1983744

Hint

有 50 个 测试点,第 i 个测试点为 n=i , \(k\leq n^2\) 。

题解

对于此题我们很难设计状态,其中最难是得保证每个数只选了一次,因此我们不能枚举每一位该填什么,而是这个数填哪个位置
由于本题性质,可以从小到大枚举方便算其贡献;

然而依旧不是那么好做,需要设计一个恰当的状态。其实预设型DP还有另外的一个名字连续段DP,我们可以设 $$f_{i,j,k}表示枚举到第 i 个数,所填位置中间有 j 个断点时总贡献为 k 的个数$$
其中 j 这一维略显突兀,用图形表示填法大致如下:

\[O()OOO()OO()O \]

连续的O表示连续填的数,()表示中间有一个断点,这个时候的j就表示有几个(),不考虑两端
我们并不会考虑()中间有多少个空位,只需知道有这么个空位就行了这就足够给出转移方程了:

分类讨论:

  • 一.放两边扩充
    1. 紧贴两边新增贡献为 i ,有两边所以计数乘 2 :
      \(f[i][j][k+i]+=f[i-1][j][k]*2\)
    2. 隔开填没有新贡献,但是会增加一个断断点,有两边所以计数乘 2 :
      \(f[i][j+1][k]+=f[i-1][j][k]*2\)
  • 二.在中间断点部分进行操作
    1. 紧贴断点两侧的连续段新增贡献为 i ,有 j 个断点 每个断点两边分别计数 所以计数乘 j*2 :
      \(f[i][j][k+i]+=f[i-1][j][k]*j*2\)
    2. 在断点中间填没有新增贡献,但会增加断点数,有 j 个断点所以计数乘 j :
      \(f[i][j+1][k]+=f[i-1][j][k]*j\)
    3. 减少一个断点,即把断点两边的连续段用我们新填的数连起来,此时贡献为 i*2,断点减少 1 ,有 j 个断点所以计数乘 j :
      \(f[i][j-1][k+2*i]+=f[i-1][j][k]*j\)

初始状态 \(f_{1,0,0}=1\)
答案 \(\displaystyle \sum^{k}_{i=1} {f_{n,0,i}}\)

这个DP设计并没有考虑中间断点的距离为多长,可以想做每个断点的距离实际上有无限长。
操作二.3 是强行把一个断点两边的连续段连在一起,考虑也只是相对位置,并不是有些题解中写的每次状态转移会筛掉一部分不合法状态的计数,或是在答案中无法体现,它都是合法的。
不要拘束于它只有 n 个可填位置,用相对位置去理解,到最后填完的时候自然就没有断点了,也正好填了那么多位。

code
const int mod=998244353;
ll f[52][52][2610];

inline void m(ll &x,const ll &y)
{
	x=(x+y)%mod;
}

signed main()
{
	int n=read(),k=read();
	
	f[1][0][0]=1;
	for(int i=2;i<=n;++i)
		for(int j=0;j<=n;++j)
			for(int u=0;u<=k;++u)
			{
				//两边 
				m(f[i][j][u+i],f[i-1][j][u]*2);//贴边
				m(f[i][j+1][u],f[i-1][j][u]*2);//空
				
				//中间
				m(f[i][j][u+i],f[i-1][j][u]*j*2);//贴边
				m(f[i][j+1][u],f[i-1][j][u]*j);//中间
				if(j)m(f[i][j-1][u+2*i],f[i-1][j][u]*j);//连接 
			}
	
	ll ans=0;	
	for(int i=0;i<=k;++i)
		m(ans,f[n][0][i]);
		
	__print(ans);
	
	return 0;
}

标签:样例,贡献,预设,计数,两边,断点,DP
From: https://www.cnblogs.com/yun233/p/18312937

相关文章

  • SharedPreferences 和 MMKV 是何方神圣
    一、概述SharedPreferences和MMKV都是Android平台保存本地数据的工具,用于保存一些常用配置。二、SharedPreferences1.类似Map集合,将Key-Value对存储于硬盘上的XML文件,以XML文件的形式保存在/data/data/包名/shared_prefs目录下。数据较多时会有性能问题。2.SharedPrefe......
  • dp-01背包
    01背包问题是动态规划中的一个经典问题,通常用于解决资源分配问题。问题描述如下:假设有一个背包,其最大承重为$W)。同时,有$n)个物品,每个物品有一个重量$w_i)和一个价值$v_i)。目标是选择一些物品放入背包,使得在不超过背包承重的前提下,背包中物品的总价值最大。问题......
  • 【MATLAB源码-第149期】基于MATLAB的2ASK,2FSK,2PSK,2DPSK等相干解调仿真,输出各节点波
    操作环境:MATLAB2022a1、算法描述2ASK(二进制幅移键控)、2FSK(二进制频移键控)、2PSK(二进制相移键控)和2DPSK(二进制差分相移键控)是数字调制技术中的基本调制方式,它们在无线通信、数据传输等领域有着广泛的应用。相干解调是这些调制方式中一个重要的解调技术,它要求接收端的本地振......
  • windows远程桌面打开rdp 调用显卡
    -----------------------------------------------------------------------------------------------------------前情提要:服务器在公网环境,带宽只有30M。远程桌面多开玩游戏,设置RDP服务端使用GPU。压缩传输带宽避免造成卡顿。如果是内网,也可以用,还可以提供一个注册表键值,修......
  • 【稳定检索】2024年数据处理与人工智能国际会议(ICDPAI 2024)
    2024年数据处理与人工智能国际会议2024InternationalConferenceonDataProcessingandArtificialIntelligence【1】会议简介        2024年数据处理与人工智能国际会议是数据处理和人工智能领域的一次重要盛会。会议旨在通过全球范围内专家学者的深入交流,探......
  • socket 收发TCP/UDP
    一、c++个人测试记录,有问题还请指出,谢谢参考:C++开发基础之网络编程WinSock库使用详解TCP/UDPSocket开发_c++udp使用什么库-CSDN博客代码中Logger测试见文章: c++中spdlog的使用/python中logger的使用-CSDN博客1、main.cpp收发TCP信号:#include<iostream>#include<thr......
  • 使用Pytorch中从头实现去噪扩散概率模型(DDPM)
    扩散模型通常是一种生成式深度学习模型,它通过学习去噪过程来创建数据。扩散模型有许多变体,其中最流行的是条件文本模型,能够根据提示生成特定的图像。某些扩散模型(如Control-Net)甚至能将图像与某些艺术风格融合。在本文中,我们将构建基础的无条件扩散模型,即去噪扩散概率模型(DDPM)。......
  • WordPress 下纯代码实现文章发布、更新后自动清理 CloudFlare 缓存
    最近明月一个参考【WordPress、Typecho站点如何让 CloudFlare 缓存加速】一文开启WordPress站点CloudFlare缓存的客户提出一个疑问,为啥新发布了文章或者修改了文章后网站首页会不能事实的同步更新?这个其实是因为客户在设置CloudFlare缓存时候边缘TTL缓存时间过长以及浏......
  • xfce下优化xrdp速度
    背景虚拟机中安装了Debian并使用了xfce4桌面,使用xrdp远程访问时感觉速度有些欠佳,应该是网络和虚拟机性能问题。解决经过测试下免费方法能够改善xrdp速度,一下在debian下xface桌面测试有效:安装xfce4和xorgxrdp-glamor设置xrdp配置修改/etc/xrdp/sesman.ini和/etc/xrdp/......
  • udp 广播通信
    基于全网段广播的代码示例,要点主要有两个:(1)设置socket属性SO_BROADCAST(2)发送方添加广播255.255.255.255的路由,不然会产生“Networkisunreachable”错误iprouteadd255.255.255.255deveth0示例代码:#include<stdio.h>#include<string.h>#include<stdlib.h>#includ......