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

预设型DP

时间:2024-08-22 20:50:33浏览次数:10  
标签:int 拓展 贡献 预设 填数 区间 DP

我们设 \(f[i][j][k]\) 表示填到 \(i\) 个数,目前拓展出 \(j\) 个可以填数的区间(最两边不算,注意是可以填数的区间!!),贡献和为 \(k\) 。

这个是可以填数的区间

我们按从小到大进行填数。

那么对于任意一个数x显然有三种情况。

1.如果x左右目前都没数,那么说明它的左右两个数都比x大,此时x的贡献为0.

2.如果x左右有一个数,那么它的贡献为x。

3.如果x左右都有数,那么它的贡献为\(2*x\)。

那我们根据这些来设计状态转移方程。

1.如果填数位置在我们已经拓展的总区间的左右边界外:

如果旁边还没填,那它就能拓展出一个可以填数的区间,左右都能拓展要乘二,但并不会增加贡献。\(f[i][j+1][k]+=f[i-1][j][k]*2\)

如果旁边已经填了,即就在左右边界旁边,则会提供 \(i\) 的贡献,区间并不拓展。\(f[i][j][k+i]+=f[i-1][j][k]*2\)

2.如果填数位置在区间内部,那它会有三种情况,一是两边都没数,二是只有一边有数,三是两边都有数,我们逐个分析:

先说第一种情况:两边都没数,那它会拓展出一个中间可填数的区间,目前有 \(j\) 个可以填数的区间,所以乘 \(j\) ,不会提供贡献。\(f[i][j+1][k]+=f[i-1][j][k]*j\)

然后是只有一边有数的情况,它会提供 \(i\) 的贡献,共有 \(j\) 个可以填数的区间,每个区间有两个已经填数的边界,所以乘 \(j*2\) ,不会拓展出区间。\(f[i][j][k+i]+=f[i-1][j][k]*j*2\)

最后一种,两边都有数,我们就同样去考虑,它首先会提供 \(2*i\) 的贡献,并且会合并两个区间,所以区间会减 \(1\) ,有 \(j\) 个可以填数的区间,所以乘 \(j\) 。\(f[i][j-1][k+2*i]+=f[i-1][j][k]*j\)

到这里,我们的分析就完成了(太不容易了)。

关于预设型DP的的感想:刚接触时,这是什么东西,还能这样设计状态,这正确性真对吗?后来仔细想了想,我个人理解是,有一些无法构成正确区间的状态在转移的时候就已经被舍去了,使一些不合法的解被排除。同时,我们的区间构造是动态的,并没有明确的左右边界。正是这些条件使得预设型DP的正确性可以得到保证。

using namespace std;


#define int long long
const int N=60;
const int mod=998244353;
int n,m,ans;
int f[N][N][2540];

signed main()
{
	scanf("%lld%lld",&n,&m);
	f[1][0][0]=1;
	for(int i=2;i<=n;i++)
	{
		for(int j=0;j<=n-i+1;j++)
		{
			for(int k=0;k<=m;k++)
			{
				f[i][j+1][k]=(f[i][j+1][k]+f[i-1][j][k]*2)%mod;
				f[i][j][k+i]=(f[i][j][k+i]+f[i-1][j][k]*2)%mod;
				if(j!=0)
				{
					f[i][j+1][k]=(f[i][j+1][k]+f[i-1][j][k]*j)%mod;
					f[i][j][k+i]=(f[i][j][k+i]+f[i-1][j][k]*j*2)%mod;
					f[i][j-1][k+i*2]=(f[i][j-1][k+i*2]+f[i-1][j][k]*j)%mod;
				}
			}
		}
	}
	for(int i=0;i<=m;i++)
	{
		ans=(ans+f[n][0][i])%mod;
	}
	printf("%lld",ans);
}`

标签:int,拓展,贡献,预设,填数,区间,DP
From: https://www.cnblogs.com/zhengchenxi/p/18374553

相关文章

  • 单调栈和单调队列优化DP
    单调栈和单调队列优化DPluoguP1725琪露诺一道比较板的题明显是一个DP,则有\[{dp}_i=\max_{j=i-r}^{i-l}dp_j+a_i\]如果暴力则为\(O(n^2)\)但是发现\(\max_{j=i-r}^{i-l}dp_j\)就是单调队列所解决的问题,所以直接单调队列维护即可#include<bits/stdc++.h>#defineFAS......
  • 131-横向移动-Kerberos攻击&SPN扫描&WinRM&WinRS&RDP
    1、RDP协议        RemoteDesktopProtocol远程桌面协议通常开放3389,Windows上面使用mstsc就可以弹出最常见的远程桌面连接方式,一般都是使用明文进行连接其实还可以使用hash进行        在内网中使用RDP协议一般是需要进行代理转发或者建立节点的端口扫......
  • 序列划分(区间DP)
    题目描述\(n\)个人,每个人手上有一个数\(a_i\)。将这些人分成若干组,组没有编号,要求每组人手上的数字之和都是质数。求合法的分组方案数。输入第一行一个正整数\(T(1\leqT\leq5)\),表示测试数据的组数。每组数据第一行一个正整数\(n(1\leqn\leq15)\)。每组数据第二行\(n\)......
  • [OI] 二项式期望 DP
    OSUOSUAnotherOSUyetAnotherOSUyetyetAnotherOSUOSU的题目是这样的:有一些相邻的块,给定每一个块的联通概率,每个连通块对答案有\(size^{3}\)的贡献,求总期望关于此题我曾写过题解此处此类题的关键之处在于,当我们设计了一个线性状态\(f_{i}\)之后,假如我们基于拼接......
  • Victor and World(状压DP)
    题目描述Aftertryinghardformanyyears,Victorhasfinallyreceivedapilotlicense.Tohaveacelebration,heintendstobuyhimselfanairplaneandflyaroundtheworld.Thereare\(n\)countriesontheearth,whicharenumberedfrom\(1\)to\(n\)......
  • 浅谈TCP和UDP协议的区别
    **传输模式**TCP协议:数据流(DataStream)--没有消息边界,比如服务端给客户端发来2048字节大小的数据,而客户端设置的一次最大接收大小为1024,这时候就意味着还有1024没能接收过来,要再接收一次。所以容易出现粘包的情况。所谓粘包,就是数据都粘在一起了。UDP协议:数据报(Da......
  • 网络编程UDP、TCP
    1UDP通信客户端UDPClientpublicclassUDPClient{publicstaticvoidmain(String[]args)throwsIOException{//获取本地服务器地址InetAddressserver_address=InetAddress.getLocalHost();//创建数据报套接字以连接到服务器......
  • DP斜率优化学习笔记
    最后一次修改:2024.7.1614:39P.MBy哈哈铭简介“斜率优化”顾名思义就是用斜率进行优化,让\(DP\)的时间复杂度更优。一般情况下,将动态转移方程化简后得到这样的关系式:\[\frac{y_1-y_2}{x_1-x_2}\leqK\]然后通过该式进行转移,以达到优化时间复杂度的目的。小tip:推公式前......
  • 服务器主机wordpress多网站启用redis缓存数据“混乱”解决办法
    近两天在搞网站数据迁移搬家的事情,是将A网站做为B网站的一个子目录,这样就牵涉到一个服务器两个网站的问题,因为这两个wordpress网站都使用了redis缓存,但在建站之初并没有设定不同的数据表前缀,后期修改我也不懂,直接导致了因为redis缓存两个网站数据“混乱”的问题。但好在网络......
  • AcWing 1078. 旅游规划 (DFS找树的直径+直径中点性质求解,无DP)
    原题链接题目描述算法引用自树的直径-OI-Wiki:若树上所有边边权均为正,则树的所有直径中点重合证明:使用反证法。设两条中点不重合的直径分别为\(\delta(s,t)与\delta(s',t')\),中点分别为\(x\)与\(x'\)。显然,\(\delta(s,x)=\delta(x,t)=\delta(s',x')=\delta(......