动态规划专项

博客围绕动态规划展开,分析了T1(P1115)、T2(B3637)、T4(P1002)、T5(P2758)几道题。给出各题状态表示、状态转移方程和初始状态,还指出错误原因多与初始状态有关,如T1要开long long,T4第1行第1列初始状态处理不当等。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

T1:P1115\tt T1:P1115T1P1115

状态:dpidp_idpi 表示以 iii 为结尾的最大子段和。
状态转移方程:dpi=max⁡(dpi−1+ai,ai)dp_i=\max(dp_{i-1}+a_i,a_i)dpi=max(dpi1+ai,ai)
初始状态:dp1=a1dp_1=a_1dp1=a1
错误原因:开 long long,要与 aia_iai 比较,要么自己加上一个,要么自己自立门户。

T2:B3637\tt T2:B3637T2B3637

状态:dpidp_idpi 表示以 iii 结尾的最大上升子序列。
状态转移方程:

for(int i=1;i<=n;i++)
	for(int j=1;j<=i-1;j++)
		if(a[i]>a[j])
			dp[i]=max(dp[j]+1,dp[i]);

初始状态:dpi=1dp_i=1dpi=1
错误原因:初始状态,dpi=1dp_i=1dpi=1

做对了,所以没有\color{white}做对了,所以没有做对了,所以没有

T4:P1002\tt T4:P1002T4P1002

状态:dpi,jdp_{i,j}dpi,j 表示起点走到 (i,j)(i,j)(i,j) 的所有路径数。
状态转移方程:

for(int i=2;i<=n;i++)
		for(int j=2;j<=m;j++)
			if(vis[i][j]==false)
				dp[i][j]=dp[i-1][j]+dp[i][j-1];

初始状态:
先要列好方向数组,将可以走到的,第 111 行第 111 列均设为 111,注意特判 (1,1)(1,1)(1,1) 可能重复。

for(int i=0;i<=8;i++)
{
   	int nx=mx+dx[i];
   	int ny=my+dy[i];
   	if(nx>=1&ny>=1&&nx<=bx&&ny<=by)
   		vis[nx][ny]=true;
}
if(vis[1][1]==false)
	dp[1][1]=1;
for(int i=2;i<=bx;i++)
    if(vis[i][1]==false)
		dp[i][1]=dp[i-1][1];
for(int i=2;i<=by;i++)
    if(vis[1][i]==false) 
		dp[1][i]=dp[1][i-1];

错误原因:初始状态的第 111 行第 111 列没有处理好。

T5:P2758\tt T5:P2758T5P2758

状态:dpi,jdp_{i,j}dpi,j 表示将 A\tt AA 串的前 iii 个字符,替换为 B\tt BB 串的前 jjj 个字符的最少操作次数。
状态转移方程:
每一个操作都用一个 dpdpdp 数组来表示。

  • 删除:dpi−1,j+1dp_{i-1,j}+1dpi1j+1。把A\tt AA 串的第 iii 个字符删除,注意算一步 +1+1+1
  • 插入:dpi,j−1+1dp_{i,j-1}+1dpij1+1。把 B\tt BB 串的第 jjj 个字符插入在 A\tt AA 串的最后面,注意算一步 +1+1+1
  • 替换:dpi−1,j−1+1dp_{i-1,j-1}+1dpi1j1+1。把A\tt AA 串的前 i−1i-1i1 个字符变为 B\tt BB 串的前 j−1j-1j1 个字符,注意算一步 +1+1+1

注意不变,也就是 dpi−1,j−1dp_{i-1,j-1}dpi1,j1

	for(int i=1;i<=n;i++)
		for(int j=1;j<=m;j++)
			if(a[i]!=b[j])
				dp[i][j]=min(dp[i-1][j],min(dp[i][j-1],dp[i-1][j-1]))+1;
			else    
				dp[i][j]=min(dp[i-1][j-1],min(dp[i][j-1]+1,dp[i-1][j]+1));

初始状态:
注意 i=0i=0i=0j=0j=0j=0 的情况,也就是将 A\tt AA 串的前 000 个字符,替换为 B\tt BB 串的前 jjj 个字符的最少操作次数与将 A\tt AA 串的前 iii 个字符,替换为 B\tt BB 串的前 000 个字符的最少操作次数。

for(int i=1;i<=n;i++)
		dp[i][0]=i;
	for(int i=1;i<=m;i++)
		dp[0][i]=i;

错误原因:初始状态,又是初始状态!

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值