动态规划题目整理

Posted 648-233

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了动态规划题目整理相关的知识,希望对你有一定的参考价值。

dp题目整理

背包问题

榨取kkksc03

因为题目中有两个限制条件,所以并不能当做一般背包问题来做,

既然限制条件(类似于"体积")多了一个,那么现在维数也多开一维,同时表示其状态

我们又发现,这个题每种物品(需求)只能取一次,所以这是一道多维0/1背包题目

那么这题就很好做了

#include<iostream>
#include<cstdio>
using namespace std;
int n,m,t;
int dp[205][205];
int mi[105];
int ti[105];
int main(){
	scanf("%d%d%d",&n,&m,&t);
	for(int i=1;i<=n;i++)
		scanf("%d%d",&mi[i],&ti[i]);
	for(int i=1;i<=n;i++)
		for(int j=t;j>=ti[i];j--)
			for(int k=m;k>=mi[i];k--)
				dp[j][k]=max(dp[j-ti[i]][k-mi[i]]+1,dp[j][k]);
	printf("%d",dp[m][t]);
	return 0;
}

求概率等的题目则更像是数学题,更需要好好分析其中的条件分析式子以推出状态转移方程

搞笑世界杯

显然,暴力枚举是不行的,那么现在考虑如何表示状态

(dp[i][j])表示A种票,B种票分别售出(i)张,(j)张时两人票相同的概率

首先考虑边界条件,

如果某一种票已经发完了,那么其概率一定是1,

就有:(dp[i][0]=dp[0][i]=1)

然后再考虑转移方程

对于当前的人,要么发到A种,要么B种,这样一来,其状态就都能够从前面状态转移而来

也就是都能从(dp[i-1][j])(dp[i][j-1])转移而来

就是这样:

(dp[i][j]=(dp[i-1][j]+dp[i][j-1])/2)

这里除以2的原因是两种情况各占一种,其概率要平均分

初始化和状态转移分析完了,剩下就只是数据处理部分了

然后代码长这样:

#include<iostream>
#include<cstdio>
using namespace std;
int n;
double dp[1255][1255];
int main(){
	scanf("%d",&n);
	n/=2;
	for(int i=2;i<=n;i++)
		dp[i][0]=dp[0][i]=1;
	for(int i=1;i<=n;i++)
		for(int j=1;j<=n;j++)
			dp[i][j]=(dp[i-1][j]+dp[i][j-1])/2.0;
	printf("%0.4lf
",dp[n][n]);
	return 0;
}

代码同样很短,这就是dp的魅力所在,用极小的篇幅带来不小的思维量

总之记住一点,dp就是前辈给后辈做出贡献的东西,后辈只能从前辈那里"学到东西"

以上是关于动态规划题目整理的主要内容,如果未能解决你的问题,请参考以下文章

[动态规划] 最长有效括号

经典动态规划——从LeetCode题海中总结常见套路

算法整理之动态规划

动态规划 洛谷P1103 书本整理

动态规划:最长重复子数组

动态规划:最长重复子数组