7.28DP训练总结

7.28DP训练总结

时间安排

8:00–8:20 读题
  • T1:将每个点的坐标转化为每个点的两个关键量而不在地图上操作,可以直接用线性DP的思路来做,枚举走过的点数,跳过的点数
  • T2:需要用这些数字得到 ≤ n \leq n n的所有数字,先想到了2的整数次幂拆分,第一问解决。但用DP求第二问的方案数思路不清晰,就先跳过了
  • T3:计算两个点之间的距离,首先想到了换根DP,但是需要花费时间推换根公式,就打算放到最后
8:20–9:20 T1

T1实现起来最简单,所以码出基本框架后花了一个多小时处理细节,刚开始DP枚举状态时,第一层循环枚举走过的点数(即状态),第二层枚举前一个点的位置,方便得到走过的距离。但是样例过了以后,造的样例过不了,发现是第二层循环枚举时不能控制跳过的点数 k k k,于是将第二层循环改成与前一个点相隔的点数,过掉了几个样例

9:20–9:40 T2

用二的整数次幂拆分得到第一问后,第二问用DP还是没思路,尝试结合之前做过的整数划分,但是发现模型压根就不同(一个是得到 n n n,一个是得到 1 − n 1-n 1n),又发现有30分 n ≤ 10 n\leq 10 n10,于是手推打了个表,先骗30分。

9:40–10:00 T3

发现和之前做的换根DP求距离差不多,无非最后在枚举一下寻找满足条件的点对,于是用之前推的公式 d i s [ n o w ] − 2 × s i z [ f a t h e r ] dis[now]-2\times siz[father] dis[now]2×siz[father],但是过不了样例,最后没有时间再思考了,就简单打了个Floyd求出所有最短距离判断,但由于时间复杂度的问题,肯定连前40分都拿不了

总结

  • T1是比较简单的DP,A掉了
  • T2只拿了30分的打表分。如果用DP得到方案数会比较难理解,所以采用 d f s + 剪枝 dfs+剪枝 dfs+剪枝也可以过掉, d f s dfs dfs的三个参数分别为目前的整数,已经选用的整数的和,选用的整数个数;边界:当整数个数等于最小个数时,判断是否 ≥ n ≥n n。剪枝:二的整次幂不断上升的和仍小于 n n n时,退出 d f s dfs dfs
  • T3:将树的根分为两部分, f [ i ] [ j ] f[i][j] f[i][j]表示到点 i i i距离为 j j j的点集个数,枚举到 n o w now now距离为 k − j k-j kj的点集个数和到 n o w now now的子节点 e d g e [ i ] . y edge[i].y edge[i].y距离为 j − 1 j-1 j1的点集个数(减去 n o w now now e d g e [ i ] . y edge[i].y edge[i].y的距离),将两部分相乘累加到答案上,然后将这两个处理过的子树合并,与下一棵子树进行状态转移即可。
> T3代码如下:

	void dfs(int now,int father)
	{
		f[now][0]=1;
		for(int i=link[now];i;i=edge[i].nxt)
		{
			if(edge[i].y==father) continue;
			dfs(edge[i].y,now);
			for(int j=1;j<=k;j++)
			{
				ans+=f[now][k-j]*f[edge[i].y][j-1];//到now距离为k-j的所有点,到edge[i].y距离为j-1的所有点 
			}
			for(int j=0;j<k;j++)
			{
				f[now][j+1]+=f[edge[i].y][j];
			}
		}
	}
总之为了A第一道题花费了较长时间,导致留给后面两道题的时间不多,最后一题的40分暴力分也没有拿到
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值