首页 > 其他分享 >背包+区间总结

背包+区间总结

时间:2023-12-23 19:55:19浏览次数:31  
标签:总结 背包 int 枚举 maxn 区间 点数

背包 DP

http://oi.nks.edu.cn/zh/Contest/Details/2519


背包和其他 DP 的不同在于,背包将物体的“代价”加入了状态,以此更好地转移

背包中最典型的的模型是 \(01\) 背包和完全背包,更难的需要用玄学做法和数据结构进行优化


单调队列优化多重背包

将背包以 $\bmod \ v $ 的余数进行分组,每一组中以单调队列维护最大值


启发式搜索解决大容量 01 背包

使用估价函数,先将物品按性价比排序,在搜索到一个状态时算出剩余物品中在剩余容量内所能获得的最大价值,如果小于当前最优解,直接剪枝

如果写法优秀,完全可以 \(0\) 毫秒通过


不选某种物品下的 01 背包方案数

设 \(f_{i,j}\) 表示前 \(i\) 个物品体积为 \(j\),的方案数,\(g_{i,j}\) 表示在所有物品中不选第 \(i\) 个物品且体积为 \(j\) 的方案数

计算 \(g_{i,j}\) 时,考虑在 \(f_{n,j}\) 中剔除第 \(i\) 个物品产生的影响

可得 \(j < a_i\) 时,\(g_{i,j} = f_{n,j}\)

把第 \(i\) 个物品当做最后一个物品考虑,有 \(f_{n,j} = g_{i,j - a_i} + g_{i,j}\)

所以 \(j \ge a_i\) 时,\(g_{i,j} = f_{n,j} - g_{i,j - a_i}\)

f[0][0] = 1;
for (int i = 1; i <= n; i++)
{
	for (int j = 0; j < a[i]; j++) f[i][j] = f[i - 1][j];
	for (int j = a[i]; j <= m; j++) f[i][j] = (f[i - 1][j] + f[i - 1][j - a[i]]) % mod;
}

for (int i = 1; i <= n; i++)
{
	for (int j = 0; j < a[i]; j++) g[i][j] = f[n][j];
	for (int j = a[i]; j <= m; j++) g[i][j] = (f[n][j] - g[i][j - a[i]] + mod) % mod;
}

21点

21点是经典的扑克玩法,玩家的目标是使手中的牌的点数之和不超过21点且尽量大。

你正在游玩一个类似的游戏,共有 \(n\) 张牌,点数分别为 \(x_1,x_2,\dots ,x_n\) 。

游戏开始时,你手里没有牌。

你可以(多次)选择在剩下的牌中等概率随机抽取一张(可以马上看到抽到的牌的点数,再做决策),或者直接进行结算。在任何时刻,你手中牌的点数之和超过 \(R\) 则游戏失败。在结算时,若你手中的牌点数之和超过 \(L\) ,则获得游戏胜利,否则也算失败。

在最优策略下,你的获胜概率最多可以达到多少?

\(f_{i,j}\) 表示选取 \(i\) 张卡片,它们的点数总和为 \(j\) 的方案数

\(g_{j,k}\) 表示不选第 \(i\) 张卡片,选取 \(j\) 张卡片,点数总和为 \(k\) 的方案数

#include <cstdio>
#include <algorithm>

const int maxn = 500 + 10;

int a[maxn];
double f[maxn][maxn];
double g[maxn][maxn];

int main()
{
	int n, l, r;
	scanf("%d %d %d", &n, &l, &r);
	for (int i = 1; i <= n; i++) scanf("%d", &a[i]);
	
	f[0][0] = 1;
	for (int i = 1; i <= n; i++)
	{
		for (int j = i; j >= 1; j--)
		{
			for (int k = 0; k < a[i]; k++) f[j][k] = f[j][k];
			for (int k = a[i]; k <= r; k++) f[j][k] = f[j - 1][k - a[i]] * j / (n - j + 1) + f[j][k];
		}
		f[0][0] = 1;
	}
	
	double ans = 0;
	for (int i = 1; i <= n; i++)
	{
		g[0][0] = 1;
		for (int j = 1; j < n; j++)
		{
			for (int k = 0; k < a[i]; k++) g[j][k] = f[j][k];
			for (int k = a[i]; k <= r; k++) g[j][k] = f[j][k] - g[j - 1][k - a[i]] * j / (n - j + 1);
		}
		
		for (int s = std::max(l - a[i] + 1, 0); s <= std::min(r - a[i], l); s++)
		{
			for (int j = 0; j < n; j++)
			{
				ans += g[j][s] / (n - j);
			}
		}
	}
	printf("%.12lf\n", ans);
	return 0;
}

 

 

 

区间 DP

http://oi.nks.edu.cn/zh/Contest/Details/2572


区间 DP 以区间长度作为阶段,每次决策时可以枚举断点或讨论端点


\(A\) 是四边形不等式,但是现在还没学会


\(B \sim I\) 的题目较为简单,状态直接设区间 \([i, j]\) 所得到的答案,转移时考虑枚举断点或直接以区间端点作为最后一步决策进行合并

\(E\) 涂色

状态还是设为将区间 \([i, j]\) 涂成目标状态所需的次数

同时,这道题还有一个关键点,就是任意两次涂色要么包含,要么不相交。如果部分相交,必然不是最优解

因此,状态转移时,可以直接枚举断点,整个区间的代价就相当于左区间代价加上右区间代价

这个前提也是保证很多区间 dp 可以枚举断点的关键,就是保证左右区间之间不会产生影响

还有一种情况就是这个区间本身就被一次性涂完,不需要枚举断点

这种情况需要保证 \(a_i = a_j\),这时就可以直接通过 \(f_{i,j-1}\) 或 \(f_{i+1,j}\) 进行转移(两种状态是等价的,不需要取 \(\min\))


\(J \sim R\) 的题目就较为复杂,原因是区间内部可能会对外部合并时产生影响,我们就需要找出影响区间外的量,并以最小代价将其储存到状态设计中

\(K\) 祖玛游戏

\(f_{i,j,k}\) 表示如果 \([i,j]\) 前有 \(k\) 个颜色与 \(a_i\) 相同的珠子,将其全部消除所需的最小次数

\(N\) 守卫

可以证明,在一个区间中,无法被右端点看到的每一个点构成的区间一定是无法被这个区间外除右端点的右边一个端点之外的点看到

因此状态可以直接用 \(f_{l,r}\) 表示覆盖区间 \([l,r]\) 所需的守卫,右端点必放,剩下的每个区间 \([i,j]\) 以 \(f_{i,j}\) 或 \(f_{i,j+1}\) 进行转移

\(O\) 字符合并

因为 \(k \le 8\),可以考虑把合并后区间的 \(01\) 串加入状态。又因为合并前的每段区间合并后也是连续的,计算 \(f_{i,j,s}\) 时可以枚举 \(s\) 的最后一位所对应的区间

\(R\) 压缩

注意到如果区间内有字母 \(M\),会对区间外产生影响,因此需要在状态表示中添加一维表示区间内是否有 \(M\),再分别讨论即可

标签:总结,背包,int,枚举,maxn,区间,点数
From: https://www.cnblogs.com/wxr-blog/p/17923536.html

相关文章

  • 2023-2024-1 20231416《计算机基础与程序设计》第十三周学习总结
    作业信息这个作业属于哪个课程https://edu.cnblogs.com/campus/besti/2023-2024-1-CFAP这个作业要求在哪里https://www.cnblogs.com/rocedu/p/9577842.html#WEEK13这个作业的目标自学《C语言程序设计》第十二章并完成云班课测试作业正文 https://www.cnblogs.co......
  • 12/23每日总结
    因为学习pythonweb没有学数据分析,但是比较感兴趣,所以来了要用到的库为numpy跟pandas,介绍如下:NumPy系统是Python的一种开源的数值计算扩展,这种工具可用来存储和处理大型矩阵,比Python自身的嵌套列表结构要高效的多(该结构也可以用来表示矩阵(matrix))。pandas是基于NumPy的一种工具,该工......
  • Nuxt3 基础总结
    前言Nuxt3的对比之前的2和1,只能感叹前端发展的越来越快了,不学无术开发更快打包更小支持vite支持vue3支持自动引入支持文件路由支持布局系统支持多种渲染模式支持typescript支持composition-api 安装NUXT3需要node大于16的版本brew更新node  bre......
  • panghu week01 总结笔记
    Algthrom:组合总和:funccombinationSum(candidates[]int,targetint)[][]int{res:=make([][]int,0)path:=make([]int,0)dfs(candidates,target,0,path,&res)returnres}funcdfs(candidates[]int,targetint,pathSumint,path[]int,res......
  • 2023-12-23训练总结
    T1计数ProblemDescriptionInputOutputSampleInputCopy210SampleOutputCopy90DataConstraint忘记初始化了调了半个小时。维护\(f_{i,0/1}\)表示长度为\(i\),最高位为\(0\)/不为\(0\)的合法方案数。明显有:\[f_{i,0}\getsf_{i-1,1}\\f_{i,1}\g......
  • 2023.12.23模拟赛总结
    前言:这次比赛又是tm的AB组一起打,tm的题目怎么一点质量都没有啊,三道简单题+一道模板题,而且模板我还没做过,而且我的一个部分换成那个模板就A了这次300pts,rank3,感觉不太好T1dp,\(f[i][0/1]\)表示i位置填0/1的方案数,直接转移,写高精度T2感觉应该放T4,实际最难首先,我们设跳楼机从0开......
  • cookie的一些知识点总结
    一、cookie的种类sessionID这个ID是会话性的,只要关闭了当前浏览器,这个ID会消失,需要调用getSessoin重新获取一个新的session会话性cookie这个cookie也是会话性的即使性cookie这个cookie只要离开的该请求或者是页面,就会消失持久性cookie这个cookie只要时间没有过期,就会存储......
  • 2023-2024-1 20231303 《计算机基础与程序设计》赵泊瑄第十三周学习总结
    2023-2024-120231303《计算机基础与程序设计》赵泊瑄第十三周学习总结作业信息这个作业属于哪个课程2023-2024-1-计算机基础与程序设计这个作业要求在哪里作业要求的链接https://i.cnblogs.com/posts/edit)这个作业的目标总结第十三周学习收获作业正文2023-......
  • 2023-2024-1 20231419 《计算机基础与程序设计》第十三周学习总结
    2023-2024-120231419《计算机基础与程序设计》第十三周学习总结作业信息这个作业属于哪个课程https://edu.cnblogs.com/campus/besti/2023-2024-1-CFAP这个作业要求在哪里https://www.cnblogs.com/rocedu/p/9577842.html#WEEK13这个作业的目标自学《C语言程序设......
  • 2023-2024-1 20231403 《计算机基础与程序设计》第十三周学习总结
    作业信息这个作业属于哪个课程<班级的链接>(如2022-2023-1-计算机基础与程序设计)这个作业要求在哪里2023-2024-1计算机基础与程序设计第十三周作业)这个作业的目标自学教材《C语言程序设计》第12章并完成云班课测试作业正文https://www.cnblogs.com/lsrmy/p/179......