汉诺塔(BZOJ) P4285 [SHOI2008]汉诺塔 居然是省选题,还是DP!(我的DP菜得要死,碰见就丢分) 冥思苦想了1h+ \(\to\) ?! 就是普通的hanoi NOI or HNOI? DP加上一个乱搞的数组,然后我还写反了一次,就gg了. 大概思路: \(dp_{i,j}\)表示从柱子i移动j个盘子的最优解,\(f_{i,j}\) 表示从柱子i移动j个盘子到哪个柱子最优.然后就可以转移了! 先把i-1个盘子从x移到 \(y=f_{x,i-1}\) ,设另一根为z,然后分类:…
P4285 [SHOI2008]汉诺塔 递推 题目给出了优先级,那么走法是唯一的. 我们用$0,1,2$代表$A,B,C$三个柱子 设$g[i][x]$为第$x$根柱子上的$i$个盘子,经过演变后最终一定会全部转移到第$g[i][x]$根柱子上 $f[i][x]$表示第$x$根柱子上的$i$个盘子,转移到第$g[i][x]$根柱子上所用的步数. 现在开始递推. 假设有$i$个盘子在第$x$个盘子上 设$y=g[i-1][x],z=3-x-y$,表示$i-1$个盘子从$x$转移到$y$后,第$i$…
洛谷P1242 新汉诺塔 最开始的思路是贪心地将盘子从大到小依次从初始位置移动到目标位置. 方法和基本的汉诺塔问题的方法一样,对于盘子 \(i\) ,将盘子 \(1\to i-1\) 放置到中间柱子上,即 \(6 - from - to\) 号柱子.基本递归实现. 但是贪心的优先将大盘移动到指定位置存在一些特殊情况处理错误. 例如如下数据,最优的方案并不是把大盘一步移到位,而是先移到了一根空柱上. 3 1 3 0 2 2 1 2 2 1 0 1 3 move 3 from A to B move…
题目链接 P4285 [SHOI2008]汉诺塔 解题思路 提供一种打表新思路 先来证明一个其他题解都没有证明的结论:\(ans[i]\)是可由\(ans[i-1]\)线性递推的. (\(ans[i]\)表示\(i\)个盘子全部移走的步数) 感谢keytoyzi神仙的神仙思路 首先,在最初两层移动的时候,遵循的移动顺序规则是题中所给的顺序. 在\(n\)个盘子都在\(A\)柱的时候,我们是怎么做的呢? 先把前\(n-1\)个盘子按照遵循初始顺序规则的方法移动到\(B\)或\(C\): 再对第\(…
洛谷P1282 多米诺骨牌 题目描述 多米诺骨牌有上下2个方块组成,每个方块中有1~6个点.现有排成行的 上方块中点数之和记为S1,下方块中点数之和记为S2,它们的差为|S1-S2|.例如在图8-1中,S1=6+1+1+1=9,S2=1+5+3+2=11,|S1-S2|=2.每个多米诺骨牌可以旋转180°,使得上下两个方块互换位置. 编程用最少的旋转次数使多米诺骨牌上下2行点数之差达到最小. 对于图中的例子,只要将最后一个多米诺骨牌旋转180°,可使上下2行点数之差为0. 输入输出格式 输入格式…
题面 Bzoj 洛谷 题解 考虑用并查集维护图的连通性,接着用线段树分治对每个修改进行分治. 具体来说,就是用一个时间轴表示图的状态,用线段树维护,对于一条边,我们判断如果他的存在时间正好在这个区间内,那就把它用并查集并起来.最后对于一个询问,直接用并查集找就好了. 但是因为有撤销操作,所以在并查集合并的时候,我们将需要合并的两个点放进栈中,最后栈序撤销,所以只能考虑按秩合并而不能路径压缩. #include <map> #include <vector> #include <…
题目描述 汉诺塔由三根柱子(分别用A.B.C表示)和n个大小互不相同的空心盘子组成.一开始n个盘子都摞在柱子A上,大的在下面,小的在上面,形成了一个塔状的锥形体. 对汉诺塔的一次合法的操作是指:从一根柱子的最上层拿一个盘子放到另一根柱子的最上层,同时要保证被移动的盘子一定放在比它更大的盘子上面(如果移动到空柱子上就不需要满足这个要求).我们可以用两个字母来描述一次操作:第一个字母代表起始柱子,第二个字母代表目标柱子.例如,AB就是把柱子A最上面的那个盘子移到柱子B.汉诺塔的游戏目标是将所有的盘子…
原题链接 题目描述 设有n个大小不等的中空圆盘,按从小到大的顺序从1到n编号.将这n个圆盘任意的迭套在三根立柱上,立柱的编号分别为A.B.C,这个状态称为初始状态. 现在要求找到一种步数最少的移动方案,使得从初始状态转变为目标状态. 移动时有如下要求: ·一次只能移一个盘: ·不允许把大盘移到小盘上面. 输入输出格式 输入格式: 文件第一行是状态中圆盘总数: 第二到第四行分别是初始状态中A.B.C柱上圆盘的个数和从上到下每个圆盘的编号: 第五到第七行分别是目标状态中A.B.C柱上圆盘的个数和从上…
传送门啦 首先要将第n个盘子从x到y,那么就要把比n小的盘子全部移到6-x-y,然后将n移到y 仔细想想:6代表的是3根初始柱,3根目标柱. 6-(x+y) 便是我们的中转柱了,因为到这个位置是最优的. 感觉题目有锅啊. #include <iostream> #include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int maxn = 55;…
题目描述 设有n个大小不等的中空圆盘,按从小到大的顺序从1到n编号.将这n个圆盘任意的迭套在三根立柱上,立柱的编号分别为A.B.C,这个状态称为初始状态. 现在要求找到一种步数最少的移动方案,使得从初始状态转变为目标状态. 移动时有如下要求: ·一次只能移一个盘: ·不允许把大盘移到小盘上面. 输入输出格式 输入格式: 文件第一行是状态中圆盘总数: 第二到第四行分别是初始状态中A.B.C柱上圆盘的个数和从上到下每个圆盘的编号: 第五到第七行分别是目标状态中A.B.C柱上圆盘的个数和从上到下每个圆…
题目描述 多米诺骨牌有上下2个方块组成,每个方块中有1~6个点.现有排成行的 上方块中点数之和记为S1,下方块中点数之和记为S2,它们的差为|S1-S2|.例如在图8-1中,S1=6+1+1+1=9,S2=1+5+3+2=11,|S1-S2|=2.每个多米诺骨牌可以旋转180°,使得上下两个方块互换位置. 编程用最少的旋转次数使多米诺骨牌上下2行点数之差达到最小. 对于图中的例子,只要将最后一个多米诺骨牌旋转180°,可使上下2行点数之差为0. 输入输出格式 输入格式: 输入文件的第一行是一个正…
P4244 [SHOI2008]仙人掌图 II 题目背景 题目这个II是和SHOI2006的仙人掌图区分的,bzoj没有. 但是实际上还是和bzoj1023是一个题目的. 题目描述 如果某个无向连通图的任意一条边至多只出现在一条简单回路(simple cycle)里,我们就称这张图为仙人掌图(cactus).所谓简单回路就是指在图上不重复经过任何一个顶点的回路.显然,仙人图上的每条边,或者是这张仙人图的桥(bridge),或者在且仅在一个简单回路里,两者必居其一.定义在图上两点之间的距离为这两点…
P4279 [SHOI2008]小约翰的游戏 题目描述 小约翰经常和他的哥哥玩一个非常有趣的游戏:桌子上有\(n\)堆石子,小约翰和他的哥哥轮流取石子,每个人取的时候,可以随意选择一堆石子,在这堆石子中取走任意多的石子,但不能一粒石子也不取,我们规定取到最后一粒石子的人算输. 小约翰相当固执,他坚持认为先取的人有很大的优势,所以他总是先取石子,而他的哥哥就聪明多了,他从来没有在游戏中犯过错误.小约翰一怒之前请你来做他的参谋.自然,你应该先写一个程序,预测一下谁将获得游戏的胜利. 输入输出格式 输…
传送门啦 本人第一个单调队列优化 $ dp $,不鼓励鼓励? 琪露诺这个题,$ dp $ 还是挺好想的对不,但是暴力 $ dp $ 的话会 $ TLE $ ,所以我们考虑用单调队列优化. 原题中说她只移动到区间 $ [i+L,i+R] $ 中的任意一格,所以我们单调队列在转移的时候 $ push $ 的应该是 $ dp[i-L] $ ,而不是 $ dp[i] $ ,对于每一段区间,我们用起点(队头)来更新答案就好了. 最后一步,因为区间的限制,我们只用在 $ [n-R+1,n] $ 中找一个最大…
题目大意:琪露诺的冰雪小屋,我做的第一道大模拟题. 题解:模拟... 卡点:无数小错误,要是没有写一点调一点,那大概是永远调不出来了... C++ Code: #include <cstdio> #include <cstring> #include <queue> #include <cstdlib> #define PutRe(x) {puts(x); return ;} inline int min(int a, int b) {return a &l…
Dominoes Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 6571   Accepted: 2178 Description A domino is a flat, thumbsized tile, the face of which is divided into two squares, each left blank or bearing from one to six dots. There is a ro…
P1282 多米诺骨牌 题目描述 多米诺骨牌有上下2个方块组成,每个方块中有1~6个点.现有排成行的 上方块中点数之和记为S1,下方块中点数之和记为S2,它们的差为|S1-S2|.例如在图8-1中,S1=6+1+1+1=9,S2=1+5+3+2=11,|S1-S2|=2.每个多米诺骨牌可以旋转180°,使得上下两个方块互换位置. 编程用最少的旋转次数使多米诺骨牌上下2行点数之差达到最小. 对于图中的例子,只要将最后一个多米诺骨牌旋转180°,可使上下2行点数之差为0. 输入输出格式 输入格式:…
https://www.luogu.org/problem/show?pid=1725 题目描述 在幻想乡,琪露诺是以笨蛋闻名的冰之妖精.某一天,琪露诺又在玩速冻青蛙,就是用冰把青蛙瞬间冻起来.但是这只青蛙比以往的要聪明许多,在琪露诺来之前就已经跑到了河的对岸.于是琪露诺决定到河岸去追青蛙.小河可以看作一列格子依次编号为0到N,琪露诺只能从编号小的格子移动到编号大的格子.而且琪露诺按照一种特殊的方式进行移动,当她在格子i时,她只会移动到i+L到i+R中的一格.你问为什么她这么移动,这还不简单,因…
P1725 琪露诺 题目描述 在幻想乡,琪露诺是以笨蛋闻名的冰之妖精.某一天,琪露诺又在玩速冻青蛙,就是用冰把青蛙瞬间冻起来.但是这只青蛙比以往的要聪明许多,在琪露诺来之前就已经跑到了河的对岸.于是琪露诺决定到河岸去追青蛙.小河可以看作一列格子依次编号为0到N,琪露诺只能从编号小的格子移动到编号大的格子.而且琪露诺按照一种特殊的方式进行移动,当她在格子i时,她只会移动到i+L到i+R中的一格.你问为什么她这么移动,这还不简单,因为她是笨蛋啊.每一个格子都有一个冰冻指数A[i],编号为0的格子冰冻…
P1725 琪露诺 题目描述 在幻想乡,琪露诺是以笨蛋闻名的冰之妖精. 某一天,琪露诺又在玩速冻青蛙,就是用冰把青蛙瞬间冻起来.但是这只青蛙比以往的要聪明许多,在琪露诺来之前就已经跑到了河的对岸.于是琪露诺决定到河岸去追青蛙. 小河可以看作一列格子依次编号为0到N,琪露诺只能从编号小的格子移动到编号大的格子.而且琪露诺按照一种特殊的方式进行移动,当她在格子i时,她只移动到区间[i+l,i+r]中的任意一格.你问为什么她这么移动,这还不简单,因为她是笨蛋啊. 每一个格子都有一个冰冻指数A[i],编…
题意 : 题目链接 分析 :  一开始这个想法也有想到,但是貌似要开很大数组,就感觉应该不行 遂放弃想其他方法,万万没想到注意到可以滚动优化(其实不优化也可以过) 定义 dp[i][j] 表示 到第 i 个数为止,凑成 j 分数所要转的最小次数 转移方程如下 若选择旋转 i 这个多米诺 dp[i][j-Sub[i]] = min( dp[i][j-Sub[i]],  dp[i-1][j] ) 若选择不旋转 dp[i][j+Sub[i]] = min( dp[i][j+Sub[i]], dp[i-…
这道题是一道背包问题,考虑一个背包, 显然如果我们直接设dp[i]表示前i个使差值最小所需的最少翻转次数,是具有后效性的. 所以我们将直接求最值,改为求某个值是否可行,这种求最值转变为求可行性的思想是非常实用的. 状态 dp[i][j]表示使用前i个物品修改得到差值j的最小步数. 第一步求出原来两个数组的总和的差值Delta(DD)是多少. 第二步进行背包DP,每个物品的质量为:t=a[i]-b[i],枚举改或不改,这样做相当于是我们企图去弥补两个数组和的差异Delta. 第三步就是找到一个能够…
传送门 https://www.cnblogs.com/violet-acmer/p/9852294.html 参考资料: [1]:https://blog.csdn.net/Darost/article/details/52517823 题解: 对于一个牌,无非就是翻转或者不翻转这两种情况,所以由此我们可以从决策入手 设dp[i][j]为前i个骨牌差值为j的最小翻牌次数 初始值全部赋值为INF; 然后f[1][a[1]-b[1]]=0, f[1][b[1]-a[i]]=1;对应于第一张牌不翻和…
水水的dp 设f[i][a][b]表示交换完前i种面值的钞票,第一个人有a元,第二个人有b元的最小代价 直接转移就行了 需要注意的是算的式子 第1个人\(\Delta A\),第二个人\(\Delta B\),最小交换代价是\((|\Delta A|+|\Delta B|+|\Delta A+\Delta B|)/2\)…
题意 类似于就是背包. 解析 代码 跟解析有点不一样v[i]价值,w[i]重量,s背包容积,背包转移即可. #include<bits/stdc++.h> using namespace std; const int maxn=1e4+5; int n,s,x,y,tot,ans; int v[maxn],w[maxn],dp[maxn]; int main(){ scanf("%d",&n); for(int i=1;i<=n;++i){ scanf(&qu…
题目:https://www.luogu.org/problemnew/show/P1282 题意: 给定n个牌,每个牌有一个上点数和下点数.可以通过旋转改变交换上下点数. 问使得上点数之和和下点数之和的差的绝对值最小的最少旋转方法. 思路: 新增一个牌,对于点数差的贡献是+a-b或-a+b 所以很自然的可以写出状态转移方程dp[i][s]=min(dp[i-1][s-a+b], dp[i-1][s+a-b]+1) 需要注意的是第二维放的是差,有可能是负数,所以要加一个偏移量. 而s的范围应该没…
传送门 首先不考虑带环的仙人掌,如果只是一棵普通的树,可以通过dp求每棵子树中的最长链和次长链求树的直径. 那么如果dfs的时候遇到了环,应该用环上的两点挂着的最长链加上两点间的距离来更新树的直径,并用环上一点的最长链加上它到环的根的距离来更新环的根的最长链. 选择环上两点来更新直径,为了考虑到所有选择,将环断开并拷贝一份新的衔接在后面,形成长为二倍的串.用dp[i]+dp[j]+j-i(i.j为在串中位置)更新直径,单调队列维护单调递减的dp[i]-i,并且如果当前点和队头的距离超过半个环就队…
#include <iostream> #include <cstdio> #include <cstring> using namespace std; int n,L,R,a[400007]; const int INF=2e8+7; int dfs(int pos){ if(pos>n) return 0; int i,k=-INF; for(i=pos+L;i<=pos+R;++i){ k=max(k,dfs(i)); } return k+a[po…
显然的DP题..... 对于位置i,它由i-r~i-l的位置转移过来,容易得到方程 dp[i]=dp[i]+max(dp[i−r],...,dp[i−l]). 第一种:n2的暴力,只能拿部分分. 1 #include<bits/stdc++.h> 2 using namespace std; 3 const int N=2e5+5,inf=0x3f3f3f3f; 4 int n,l,r,a[N],dp[N],ans=-inf; 5 6 int main(){ 7 scanf("%d%…
[BZOJ1019][SHOI2008]汉诺塔(数论,搜索) 题面 BZOJ 洛谷 题解 首先汉诺塔问题的递推式我们大力猜想一下一定会是形如\(f_i=kf_{i-1}+b\)的形式. 这个鬼玩意不好算,我们就拿着\(f_1,f_2,f_3\)之间的关系算一下,爆搜一下很容易解出直线方程. #include<iostream> #include<cstdio> using namespace std; int n,m,k,b;char ch[2]; int E[6][2];long…